根据Apple docs我们应该做这样的事情来处理 GC 身份验证:
- (void) authenticateLocalUser
{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
if(localPlayer.authenticated == NO)
{
[localPlayer setAuthenticateHandler:(^(UIViewController* viewcontroller, NSError *error) {
if (!error && viewcontroller)
{
DLog(@"Need to log in");
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[appDelegate.window.rootViewController presentViewController:viewcontroller animated:YES completion:nil];
}
else
{
DLog(@"Success");
}
})];
}
}
我们得到了以下信息:
如果设备没有经过身份验证的玩家,Game Kit 会将 View Controller 传递给您的身份验证处理程序。呈现时,此 View Controller 显示身份验证用户界面。你的游戏应该暂停其他需要用户交互的事件(比如你的游戏循环),呈现这个 View Controller 然后返回。当玩家完成与其交互时, View Controller 会自动关闭。
我的问题是,我们如何知道这个 View Controller 何时被关闭,以及我们如何知道身份验证是否成功?
很明显,我需要知道身份验证是否有效,并且我需要知道如果我不得不暂停游戏,何时恢复游戏,因为出现了神奇的 GC View Controller 。
最佳答案
您的代码存在问题:首先,您应该在应用加载后立即设置身份验证处理程序。这意味着无论 localPlayer 是否通过身份验证,您都可以设置处理程序,以便在玩家注销并再次登录时自动调用它。如果您的玩家从您的应用程序切换到游戏中心应用程序,并注销/登录,则不会调用您应用程序中的处理程序(如果他在应用程序首次启动时已经通过身份验证)。设置处理程序的目的在于,每次发生身份验证更改(输入/输出)时,您的应用程序都可以做正确的事情。
其次,你不应该依赖错误来做任何事情。即使返回错误,游戏工具包可能仍具有足够的缓存信息来为您的游戏提供经过身份验证的玩家。这些错误只是为了帮助您进行调试。
要回答您的问题,请先查看下面的代码示例。
-(void)authenticateLocalPlayer
{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
//Block is called each time GameKit automatically authenticates
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error)
{
[self setLastError:error];
if (viewController)
{
self.authenticationViewController = viewController;
[self disableGameCenter];
}
else if (localPlayer.isAuthenticated)
{
[self authenticatedPlayer];
}
else
{
[self disableGameCenter];
}
};
}
-(void)authenticatedPlayer
{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
[[NSNotificationCenter defaultCenter]postNotificationName:AUTHENTICATED_NOTIFICATION object:nil];
NSLog(@"Local player:%@ authenticated into game center",localPlayer.playerID);
}
-(void)disableGameCenter
{
//A notification so that every observer responds appropriately to disable game center features
[[NSNotificationCenter defaultCenter]postNotificationName:UNAUTHENTICATED_NOTIFICATION object:nil];
NSLog(@"Disabled game center");
}
在我的应用程序中,对 authenticateLocalPlayer
的调用仅在应用程序启动时调用一次。这是因为在此之后会自动调用处理程序。
how do we know when this view controller gets dismissed,
你不会知道这个 View Controller 什么时候被关闭。 文档中的代码示例说在适当的时候显示 View Controller 。这意味着您不必在游戏中心无法登录时每次 都显示 View Controller 。事实上,您可能不应该立即在处理程序中显示它。您应该仅在您的玩家有必要继续执行手头的任务时才显示 View Controller 。它不应该在奇怪的时间弹出。这就是我保存 View Controller 的原因,以便稍后在需要时显示。
I need to know when to resume the game if I had to pause it because the magic GC view controller was presented.
如果您将身份验证处理程序设置为根据状态更改发布通知,您可以监听事件并显示“暂停菜单”或其他内容,直到用户选择恢复。
how do we know if the authentication succeeded
如果身份验证成功,则 View Controller 为 nil,localPlayer.isAuthenticated
为 true。
or not ?
如果身份验证失败,则 localPlayer.isAuthenticated
为 false,并且 View Controller 为 nil。身份验证失败可能由于多种原因(网络等)而发生,在这种情况下您不应该呈现 View Controller ,这就是 View Controller 将为零的原因。在这种情况下,您应该禁用游戏中心功能直到用户接下来登录。由于身份验证处理程序是自动调用的,因此大多数时候您不需要做任何事情。如果您想提示用户在游戏中心做一些您无法通过代码自动完成的事情,您始终可以提供一种从您的应用程序启动游戏中心应用程序的方法。
编辑:使用像 self.isAuthenticated
这样的标志(正如我上面所做的那样)来跟踪您是否登录不是一个好主意(我不想造成任何困惑,所以我没有删除它)。最好始终检查 [GKLocalPlayer localPlayer].isAuthenticated
编辑:稍微清理了代码 - 删除了不必要的 self.isAuthenticated 和不需要的 block 变量。
关于ios - 处理 Game Center 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20291922/