6

我的应用会记录它是否成功通过 Game Center 的身份验证。当它开始一个新游戏或当用户查看分数列表时,如果本地玩家没有成功验证,并且如果应用程序当时没有尝试验证用户,它会再次尝试.

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

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

在登录失败后,当我去做一些导致重新验证检查发生的事情时,我得到了这个:

2012-09-25 15:54:47.829 应用程序名称 [1493:907] * 断言失败 -[UIWindowController 转换:fromViewController:toViewController:target:didEndSelector:],/SourceCache/UIKit/UIKit-2372/UIWindowController.m:211

然后这实际上崩溃了:

2012-09-25 15:55:25.569 应用程序名称 [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];
             }
             ];
        }
    }
}

知道我在这里做错了什么吗?

4

3 回答 3

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

    }
})];
于 2012-09-26T09:23:17.217 回答
3

Jamie West 正确地指出,问题在于 iOS6 中的 authenticateHandler 转换,这似乎导致 authenticateWithCompletionHandler: 损坏。由于它已被弃用,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(可能还有其他情况,而不是取消?)。

如果用户已经离开并做了其他事情,它在应用程序从睡眠中被调用时尝试重新验证。

于 2012-09-26T19:31:31.703 回答
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,它就修复了所有问题,即使是不推荐使用的调用方式。(参考这个问题

- (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
}
于 2013-02-26T00:50:42.440 回答