iOS 6游戏中心authenticateHandler因取消登录而无法登录

26

在iOS 6中使用authenticateHandler时,如果用户取消了登录视图,game center将不会呈现该视图。我知道game center会自动锁定应用程序,经过3次取消尝试后,但是我指的是只有2次尝试的情况。如果他们取消了登录,他们必须离开应用并返回才能再次显示登录,即使设置了authenticateHandler也是如此。有没有想法如何处理这种情况在iOS 6中?

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

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

1
听起来你已经在做这个了,但是调用[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:nil]会导致authenticateHandler再次被调用并显示一个认证视图控制器。然而,在iOS6中,这个方法已经被弃用了。 - Greg
1
这个有更新了吗?我有一个“加载”屏幕,他们必须进行身份验证,所以我只想在那里放一个按钮来再次拉起它。现在我只会使用一个ivar并警告他们。 - Mohammad El-Abid
1
仍然没有更新。听起来大多数人使用已弃用的调用来解决这个问题。 - Tod Cunningham
@TodCunningham,你解决了吗?即使在你发布1.5年后,我仍然面临同样的问题。 - Dima Deplov
不好意思,这个问题还存在。 - Tod Cunningham
显示剩余2条评论
2个回答

2

最好使用运行时检查(instancesRespondToSelector :),而不是预处理器#if语句,这样您可以在推荐方法可用的地方使用它们,并在其他地方使用过时的方法。实际上,我发现在设置邀请处理程序之前需要区分三种情况,因为认证处理程序也可能使用空视图控制器调用:

 -(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];
         }];
     }
 }

在邀请处理程序中需要区分更多的情况,因为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
            }
        };
    }
}

如果这有帮助,请告诉我。


1
预处理器宏仅用于调试和显示问题。我遇到的问题是,如果用户取消Game Center显示的初始登录,则无法使用iOS 6公共API触发登录。早期的iOS 6 API通过重置处理程序来支持此行为。 - Tod Cunningham

0

我认为在iOS 6.0中这是不可能的。在正式发布之前,早期SDK版本中有用于此的API调用被删除了。

在WWDC 2012视频:Session 516 - Integrating Your Games with Game Center [8:30]中,他们实际上展示了一段代码,其中你可以调用一个authenticate方法:

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]];

我认为在实际代码中这样做是不可取的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接