GKLocalPlayer在iOS6上使用模态转换错误进行Auth崩溃

时间:2012-09-25 23:05:08

标签: ios ios6 game-center

我的应用程序记录了它是否已成功通过Game Center验证。当它开始新游戏或用户查看分数列表时,如果本地播放器未成功通过身份验证,并且该应用程序当时未尝试对用户进行身份验证,则会再次尝试。

(为什么?如果您从无网络区域移动到网络区域。)

不幸的是,在iOS6 / XCode 4.5下,它开始崩溃了。或者至少在某些有限的情况下似乎:用户无法使用错误的密码和/或不存在的帐户登录。成功登录后,一切顺利。

在登录失败后,当我去做一些导致进行reauth检查的事情时,我得到了这个:

  

2012-09-25 15:54:47.829 APP NAME [1493:907] *   断言失败 - [UIWindowController   过渡:fromViewController:toViewController:目标:didEndSelector:],   /SourceCache/UIKit/UIKit-2372/UIWindowController.m:211

然后这实际上崩溃了:

  

2012-09-25 15:55:25.569 APP NAME [1493:907] *   由于未捕获的异常而终止应用程序   'NSInternalInconsistencyException',原因:'尝试开始一个   来自< GKModalRootViewController的模态转换:0x1cd8b2a0>至   < GKHostedAuthenticateViewController:0x1e31a350>虽然转型是   已经在进行中。等待viewDidAppear / viewDidDisappear知道   目前的转型已经完成   * 第一次抛出调用堆栈:(0x394932a3 0x31db297f 0x3949315d 0x383fd2af 0x3640377b 0x36402fcf 0x394969c4 0x393edfeb 0x36521733   0x32a83d2d 0x3264b11f 0x3264a4b7 0x3264f1bd 0x39466f3b 0x393d9ebd   0x393d9d49 0x353132eb 0x3636b301 0x7e863 0x7e808)libc ++ abi.dylib:   终止调用抛出异常

这是一个麻烦的代码:

-(void)authenticateLocalUser {

    if (!self.checkingLocalPlayer) {
        self.checkingLocalPlayer = YES;
        GKLocalPlayer *thisPlayer = [GKLocalPlayer localPlayer];

        if (!thisPlayer.authenticated) {

            [[GKLocalPlayer localPlayer]
             authenticateWithCompletionHandler:^(NSError *error)
             {
                 [self finishGameCenterAuthWithError:error];
             }
             ];
        }
    }
}

知道我在这里做错了吗?

3 个答案:

答案 0 :(得分:7)

Ggrrrhhh同样的问题,想想我发现它... ios6已弃用authenticateWithCompletionHandler看到链接,建议你使用AuthenticateHandler。

http://developer.apple.com/library/IOS/#documentation/GameKit/Reference/GKLocalPlayer_Ref/Reference/Reference.html#//apple_ref/occ/instp/GKLocalPlayer/authenticateHandler

这似乎有用......

GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
[localPlayer setAuthenticateHandler:(^(UIViewController* viewcontroller, NSError *error) {

//[localPlayer authenticateWithCompletionHandler:^(NSError *error) { OLD CODE!
    if (localPlayer.isAuthenticated)
    {
        //do some stuff
    }
    else {

        UIAlertView *alertView = [[UIAlertView alloc]
                                  initWithTitle:@"NOT AUTHORISED"
                                  message:@"YOUR'RE NOT LOGGED INTO GC."
                                  delegate:self
                                  cancelButtonTitle:@"OK"
                                  otherButtonTitles:nil];
        [alertView show];

    }
})];

答案 1 :(得分:3)

Jamie West正确地指出问题是转换到iOS6中的authenticateHandler,它似乎已经遗留了authenticateWithCompletionHandler:broken。由于它已被弃用,Apple不太可能修复它们的错误。

这是我需要的一切。注意检查iOS5版本的条件(支持5和6)以及调用视图控制器的需要(例如,authenticateHandler:不是authenticateWithCompletionHandler的直接替代: - 你必须做一些额外的工作)。

-(void)authenticateLocalUser {

    if (!self.checkingLocalPlayer) {
        self.checkingLocalPlayer = YES;
        GKLocalPlayer *thisPlayer = [GKLocalPlayer localPlayer];

        if (!thisPlayer.authenticated) {

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

            if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {

                [thisPlayer setAuthenticateHandler:(^(UIViewController* viewcontroller, NSError *error) {

                    if (viewcontroller) {
                        [self.delegate presentViewController:viewcontroller];
                    } else {
                        [self finishGameCenterAuthWithError:error];
                    }

                })];

            } else {

                [[GKLocalPlayer localPlayer]
                 authenticateWithCompletionHandler:^(NSError *error)
                 {
                     [self finishGameCenterAuthWithError:error];
                 }
                 ];
            }

        }
    }
}

presentViewController:函数只是从我的顶视图控制器中调用新的视图控制器(我必须在我的程序中手工弄清楚才能完成所有这些工作):

-(void)presentViewController:(UIViewController *)thisVC {

    [myTopVC presentModalViewController:thisVC animated:YES];

}

不幸的是,从iOS6开始,如果用户已经在当前会话中取消了,那么看起来GameCenter将不会尝试重新命名用户,因此至少在适当的时候我的一些重新发送点已经消失。但是,它仍然适用于iOS5(也许还有其他情况而不是取消?)。

当用户已经离开并完成其他操作时,如果从睡眠状态调用该应用程序, 将尝试reauth。

答案 2 :(得分:1)

我有完全相同的问题和类似的崩溃消息和上述答案没有解决问题。

2012-09-25 15:55:25.569 APP NAME [1493:907] * Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: 'Attempting to begin a modal transition from
<GKModalRootViewController: 0x1cd8b2a0> to <GKHostedAuthenticateViewController: 0x1e31a350>
 while a transition is already in progress. Wait for viewDidAppear/viewDidDisappear to know
the current transition has completed' 

实际上导致问题的是我从 - (void)viewDidLoad调用了 - (void)authenticateLocalPlayer。一旦我将调用移到 - (void)viewDidAppear,它就修复了所有内容,即使是不推荐的调用方式。 (reference to this question

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    //Setup Game Center Manager
    if ([GameCenterManager isGameCenterAvailable]) {  
        delegate.gameCenterManager = [[GameCenterManager alloc] init];
        [delegate.gameCenterManager setDelegate:delegate];
        [delegate.gameCenterManager authenticateLocalUser];
    } else {
        // The current device does not support Game Center.
    }

    //... more things if you have
}