【问题标题】:GKLocalPlayer authentication not working, but isAuthenticated returns YES (Game Center sandbox)GKLocalPlayer 身份验证不起作用,但 isAuthenticated 返回 YES(游戏中心沙盒)
【发布时间】:2014-05-08 12:26:07
【问题描述】:

我正在努力在我的游戏中集成回合制比赛,几天前我开始从 GameKit API 中收到奇怪的错误,说本地玩家没有经过身份验证,即使他是。

当我启动应用程序时,调用authenticateHandler,显示视图控制器,输入密码后,再次调用authenticaHandler,本地播放器似乎已通过身份验证。 isAuthenticated 返回YES

但是,一旦我开始使用任何 GameKit API,例如 loadFriendsWithCompletionHandler:,就会返回一个错误,指出玩家尚未通过身份验证。

这是处理身份验证更改的代码。

[[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 “请求的操作无法完成,因为本地播放器尚未通过身份验证。” UserInfo=0x14e9f950 {NSLocalizedDescription=请求的操作无法完成,因为本地播放器尚未通过身份验证。}
(lldb) 打印 (BOOL) [[GKLocalPlayer localPlayer] isAuthenticated] (BOOL) $3 = 是

我在 Game Center 沙盒中进行测试,几天前就开始发生这种情况。以前,我根本没有遇到过这个问题。
它只在应用程序启动时发生大约三次。我已经尝试过删除应用程序、重新启动设备、清理构建文件夹以及我能想到的所有其他内容。

我是否遗漏了什么或其他人遇到过类似的问题?

【问题讨论】:

  • 您知道如何解决此错误吗?我的游戏出现此弹出错误。

标签: ios objective-c game-center gamekit


【解决方案1】:

这个有钱的Apple documentation 是个值得一看的好地方。以下是我建议的两件事 -

  1. 如果您的设备有 日期不正确。所以,继续检查当前日期。

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

您认为您使用-[GKLocalPlayer loadFriendsWithCompletionHandler:] 的方式有问题吗?您上面的身份验证功能没有任何问题,但如果它适合您,我很乐意分享我的 -

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

【讨论】:

  • 不仅可以加载好友,还可以结束回合或报告成就。这种情况不再经常发生,所以我认为这可能只是 Game Center 沙盒服务器的临时问题。无论如何,感谢您的帮助。
【解决方案2】:

您为什么使用 Game Kit 框架? 从 iOS 7 开始,您应该使用 MultipeerConnectivity。

1) – authenticateWithCompletionHandler:在 iOS 6.0 中已弃用。 如果您在 iOS 7 上进行测试,它可能根本无法运行。

2) 以下示例通过 MultipeerConnectivity 创建连接

客户:

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

【讨论】:

  • 我将 GameKit 用于成就和排行榜,但不能使用 MultipeerConnectivity。
  • 确保“新玩家可能已登录设备或玩家可能只是从 Game Center 注销。” developer.apple.com/library/ios/documentation/GameKit/Reference/…
  • 我正在我的设备上测试这个,我是唯一的用户。抱歉,但我认为您不理解我的问题。
  • 上面这位先生用 MultipeerConnectivity 代码解决了这个问题!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多