Ios6 iOS 6游戏中心authenticateHandler可以';在取消后不能登录

Ios6 iOS 6游戏中心authenticateHandler可以';在取消后不能登录,ios6,game-center,Ios6,Game Center,在iOS 6中使用authenticateHandler时,如果用户取消登录,game center将不会显示登录视图。我意识到游戏中心会在3次取消尝试后自动锁定一个应用程序,但我说的只是2次尝试。如果他们取消登录,即使authenticateHandler再次设置,他们也必须在game center显示登录之前离开应用程序并返回。关于如何在iOS 6中处理这个问题有什么想法吗 当使用旧的authenticateWithCompletionHandler方法时,它可以正常工作: #if __IP

在iOS 6中使用authenticateHandler时,如果用户取消登录,game center将不会显示登录视图。我意识到游戏中心会在3次取消尝试后自动锁定一个应用程序,但我说的只是2次尝试。如果他们取消登录,即使authenticateHandler再次设置,他们也必须在game center显示登录之前离开应用程序并返回。关于如何在iOS 6中处理这个问题有什么想法吗

当使用旧的authenticateWithCompletionHandler方法时,它可以正常工作:

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0
    GKLocalPlayer.localPlayer.authenticateHandler = authenticateLocalPlayerCompleteExtended;
#else
    [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:authenticateLocalPlayerComplete];
#endif
这对我的应用程序很重要的原因是它需要多人游戏中心。该应用程序尝试在启动时向游戏中心进行身份验证,但如果用户取消,我们不会在启动时再次询问他们,这样他们就不会被唠叨。我们要做的是显示一个游戏中心登录按钮,如果他们没有登录时,他们选择多人。“登录”按钮通过调用authenticateWithCompletionHandler(现在再次设置GKLocalPlayer.localPlayer.authenticateHandler)强制游戏中心登录。

最好使用运行时检查(InstanceRespondtoSelector:)而不是预处理器if语句,因此,您可以在可用的地方使用推荐的方法,而在其他地方使用已折旧的方法。实际上,我发现在设置invite处理程序之前需要区分三种情况,因为身份验证处理程序也可能会被nil视图控制器调用:

 -(void)authenticateLocalPlayer
 {
     if ([[GKLocalPlayer class] instancesRespondToSelector:@selector(setAuthenticateHandler:)]) {
         [[GKLocalPlayer localPlayer] setAuthenticateHandler:^(UIViewController *gameCenterLoginViewController, NSError *error) {
             if (gameCenterLoginViewController) {
                 [self.presentedViewController presentViewController:gameCenterLoginViewController
                                                            animated:YES
                                                          completion:^{
                                                              [self setInviteHandlerIfAuthenticated];
                                                          }];
             } else {
                 [self setInviteHandlerIfAuthenticated];
             }
         }];
     } else { // alternative for iOS < 6
         [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error) {
             [self setInviteHandlerIfAuthenticated];
         }];
     }
 }
-(无效)AuthenticateLocalLayer
{
if([[GKLocalPlayer类]实例响应选择器:@selector(setAuthenticateHandler:)])){
[[GKLocalPlayer localPlayer]setAuthenticateHandler:^(UIViewController*gameCenterLoginViewController,NSError*错误){
if(gameCenterLoginViewController){
[self.presentedViewController当前视图控制器:gameCenterLoginViewController
动画:是的
完成:^{
[self-SetInvitedHandlerIfauthenticated];
}];
}否则{
[self-SetInvitedHandlerIfauthenticated];
}
}];
}else{//iOS<6的替代方案
[[GKLocalPlayer]authenticateWithCompletionHandler:^(N错误*错误){
[self-SetInvitedHandlerIfauthenticated];
}];
}
}
然而,在invite处理程序中还必须区分更多的情况,因为matchForInvite::在iOS6中也是新的,它避免了通过游戏中心视图控制器进行另一轮操作:

-(void)setInviteHandlerIfAuthenticated
{
    if ([GKLocalPlayer localPlayer].isAuthenticated) {
        [GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) {
            if (acceptedInvite) {
                if ([GKMatchmaker instancesRespondToSelector:@selector(matchForInvite:completionHandler:)]) {
                    [self showInfoAnimating:YES completion:NULL];
                    [[GKMatchmaker sharedMatchmaker] matchForInvite:acceptedInvite
                                                  completionHandler:^(GKMatch *match, NSError *error) {
                                                      // ... handle invited match
                                                  }];
                } else {
                    // alternative for iOS < 6
                    GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite] autorelease];
                    mmvc.matchmakerDelegate = self;
                    // ... present mmvc appropriately
                    // ... handle invited match found in delegate method matchmakerViewController:didFindMatch:
                 }
            } else if (playersToInvite) {
                 // ... handle match initiated through game center
            }
        };
    }
}
-(void)SetInviteHandler已验证
{
如果([GKLocalPlayer].isAuthenticated){
[GKMatchmaker sharedMatchmaker].inviteHandler=^(GKInvite*acceptedInvite,NSArray*PlayerToInvite){
如果(接受邀请){
if([GKMatchmaker InstanceRespondtoSelector:@selector(matchForInvite:completionHandler:)])){
[自显示信息动画:是完成:空];
[[GKMatchmaker sharedMatchmaker]matchForInvite:已接受邀请
completionHandler:^(GKMatch*match,NSError*error){
//…处理邀请赛
}];
}否则{
//iOS<6的替代方案
GKMatchmakerViewController*mmvc=[[GKMatchmakerViewController alloc]initWithInvite:acceptedInvite]autorelease];
mmvc.matchmakerDelegate=self;
//…适当地呈现mmvc
//…在委托方法matchmakerViewController:didFindMatch中找到句柄邀请匹配:
}
}else if(playersToInvite){
//…处理通过游戏中心启动的比赛
}
};
}
}

如果有帮助,请告诉我。

我认为这在iOS 6.0中是不可能的。在发布之前删除的早期SDK构建中,有一些API调用可以实现这一点

在WWDC 2012视频:第516课时-将您的游戏与游戏中心集成[8:30]中,它们实际显示了您调用
验证
方法的代码:

GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticationHandler = //handle the callback...
[localPlayer authenticate];
此方法现在是私有API,但您可以通过调用以下命令来查看它的操作:

[[GKLocalPlayer localPlayer] performSelector:@selector(_authenticate)];
它完全是你想要的,但不能使用,因为它现在是私有的


您还可以通过发布
UIApplicationWillEnterForegroundNotification
通知来触发身份验证过程:

[[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillEnterForegroundNotification object:[UIApplication sharedApplication]];

我认为在实时代码中这样做是不明智的。

听起来您已经在这样做了,但是调用[[GKLocalPlayer localPlayer]authenticateWithCompletionHandler:nil]将导致authenticateHandler被身份验证视图控制器再次调用。尽管在iOS6中,此方法已被弃用。我正在使用已弃用的调用来实现此目的,但我正在寻找一种“正确”的方法来实现此目的,而不使用弃用的调用。我尝试将新的GKLocalPlayer.localPlayer.authenticateHandler设置为nil,然后返回到我的处理程序以查看这是否可行,但尝试将其设置为nil时出现异常。我没有尝试将其设置为不同的处理程序,以查看是否会触发登录(这看起来真的很糟糕),我尝试将处理程序切换到另一个处理程序,这也不会触发打开新的登录对话框。我在开发者论坛上发帖,看看有没有人有什么建议,如果我听到什么,我会发帖回这里。这方面有更新吗?我有一个“加载”屏幕,他们必须在那里进行身份验证,所以我只想在那里有一个按钮来再次拉它。现在我只给我们一个ivar并通知他们。仍然没有更新。听起来大多数人使用折旧调用是为了解决这个问题。预处理器宏只是为了调试和显示