GKLocalPlayer身份validation不起作用,但isAuthenticated返回YES(游戏中心沙箱)

我正在整合我的游戏中的基于回合的比赛,并且几天前我开始从GameKit API中发现奇怪的错误,说本地玩家没有通过身份validation,即使他是。

当我启动应用程序时,调用authenticateHandler ,显示视图控制器,input密码后,再次调用authenticaHandler ,本地播放器似乎被authentication。 isAuthenticated返回YES

但是,一旦我开始使用任何GameKit API(例如loadFriendsWithCompletionHandler: ,就会返回错误信息,说明播放器尚未经过身份validation。

这是处理authentication更改的代码。

 [[GKLocalPlayer localPlayer] setAuthenticateHandler:^(UIViewController *viewController, NSError *error) { if ([[GKLocalPlayer localPlayer] isAuthenticated]) { // Player authenticated } else { // Player not authenticated if (viewController != nil) { // Present view controller } } }]; 

这是调用任何GameKit方法时收到的错误消息。 请注意,返回错误时, -isAuthenticated仍然返回YES。

找不到匹配项:Error Domain = GKErrorDomain Code = 6“请求的操作无法完成,因为本地播放器尚未validation。 UserInfo = 0x14e9f950 {NSLocalizedDescription =请求的操作不能完成,因为本地播放器没有被authentication。}
(lldb)print(BOOL)[[GKLocalPlayer localPlayer] isAuthenticated](BOOL)$ 3 = YES

我正在Game Center沙盒中testing,并在几天前开始发生。 以前,我根本没有遇到这个问题。
它只发生在应用程序启动时的三次之一。 我试过删除应用程序,重新启动我的设备,清理生成文件夹和其他所有我能想到的。

我是否错过了某些东西,或者有其他人遇到过类似的问题?

这个丰富的苹果文档是一个很好的地方。 这里有两件事我build议 –

  1. 如果您的设备有不正确的date,Game Center将无法完成身份validation。 所以,继续检查当前的date。

  2. 你可能已经做到了。 我相信你 – iOS模拟器>>重置内容和设置

你认为你使用的方式可能有问题-[GKLocalPlayer loadFriendsWithCompletionHandler:] ? 上面的authenticationfunction没什么问题,但是我很乐意分享一下,如果它适合你的话 –

 -(void)authenticateLocalPlayer{ // Instantiate a GKLocalPlayer object to use for authenticating a player. GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer]; localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error){ if (viewController != nil) { // If it's needed display the login view controller. [self presentViewController:viewController animated:YES completion:nil]; } else { if ([GKLocalPlayer localPlayer].authenticated) { // If the player is already authenticated then indicate that the Game Center features can be used. _gameCenterEnabled = YES; } else { _gameCenterEnabled = NO; } } }; } 

你为什么使用游戏套件框架? 从iOS 7你应该使用MultipeerConnectivity。

1) – authenticateWithCompletionHandler:在iOS 6.0中不推荐使用。 如果你在iOS 7上testing,它可能根本不起作用。

2)下面的示例通过MultipeerConnectivity创build连接

客户:

 - (id)init { self = [super init]; if (self) { NSString *peerName = [NSString stringWithFormat:@"%@-%@", @"Client", [[UIDevice currentDevice] identifierForVendor].UUIDString]; self.myPeerID = [[MCPeerID alloc] initWithDisplayName:peerName]; self.servers = [NSMutableArray array]; self.session = [[MCSession alloc] initWithPeer:self.myPeerID securityIdentity:nil encryptionPreference:MCEncryptionNone]; self.session.delegate = self; self.browser = [[MCNearbyServiceBrowser alloc] initWithPeer:self.myPeerID serviceType:@"Connect"]; self.browser.delegate = self; [self.browser startBrowsingForPeers]; } return self; } //----- - (void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info { NSLog(@"client: found a server: %@", peerID); [self.browser invitePeer:peerID toSession:self.session withContext:nil timeout:10]; } - (void)browser:(MCNearbyServiceBrowser *)browser lostPeer:(MCPeerID *)peerID { NSLog(@"client: lost server: %@", peerID); } #pragma mark - MCSessionDelegate - (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state { NSLog(@"client: status changed to %d for server: %@", state, peerID.displayName); switch (state) { case MCSessionStateNotConnected: { } break; case MCSessionStateConnected: { } break; default: break; } } - (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID { NSLog(@"client: received data (len = %lu) from server %@",(unsigned long)[data length], peerID.displayName); NSDictionary *receiveDictionary = (NSDictionary*) [NSKeyedUnarchiver unarchiveObjectWithData:data]; } 

服务器:

 - (id)init { self = [super init]; if (self) { NSString *peerName = [NSString stringWithFormat:@"%@-%@", @"Server", [[UIDevice currentDevice] identifierForVendor].UUIDString]; self.myPeerID = [[MCPeerID alloc] initWithDisplayName:peerName]; self.session = [[MCSession alloc] initWithPeer:self.myPeerID]; self.session.delegate = self; self.advertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:self.myPeerID discoveryInfo:nil serviceType:@"Connect"]; self.advertiser.delegate = self; [self.advertiser startAdvertisingPeer]; } return self; } #pragma mark - MCNearbyServiceAdvertiserDelegate - (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler { NSLog(@"server: did receive invitation from peer %@", peerID.displayName); invitationHandler(YES, self.session); } - (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didNotStartAdvertisingPeer:(NSError *)error { NSLog(@"server: error %@", error); } #pragma mark - MCSessionDelegate - (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state { NSLog(@"server: status changed to %ld for client: %@", state, peerID.displayName); switch (state) { case MCSessionStateConnected: { NSMutableDictionary *sendDict = [NSMutableDictionary dictionary]; NSError *error = nil; [self.session sendData:[NSKeyedArchiver archivedDataWithRootObject:sendDict] toPeers:@[peerID] withMode:MCSessionSendDataReliable error:&error]; } break; case MCSessionStateNotConnected: break; default: break; } NSLog(@"connectedPeers %@", self.session.connectedPeers); } - (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID { NSLog(@"server: received data (len = %lu) from client %@", (unsigned long)[data length], peerID.displayName); NSDictionary *dictionary = (NSDictionary*) [NSKeyedUnarchiver unarchiveObjectWithData:data]; } - (void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID { } - (void)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress { } - (void)session:(MCSession *)session didFinishReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID atURL:(NSURL *)localURL withError:(NSError *)error { } - (void)session:(MCSession*)session didReceiveCertificate:(NSArray*)certificate fromPeer:(MCPeerID*)peerID certificateHandler:(void (^)(BOOL accept))certificateHandler { certificateHandler(YES); }