我已经使用了[[GKTurnBasedEventHandler sharedTurnBasedEventHandler] setDelegate:self];,但没有收到委托调用。这在某一点上是有效的,我无法弄清发生了什么变化。

该应用已正确标记(在设备主屏幕上,它显示一个标记,其中包含轮到我玩的游戏数量)。此外,使用GKTurnBasedMatch loadMatchesWithCompletionHandler:能够检测到玩家轮到(或不算)轮到什么时候。实际上,以其他所有可能的方式,GameCenter似乎都能正常运行。我什至可以发送(并接受)挑战,但是同样,不会调用委托方法:不会调用任何GKTurnBasedEventHandlerDelegate方法(包括handleTurnEventForMatch:handleInviteFromGameCenter:等)。

甚至变得更奇怪:如果我完全退出了该应用程序并且轮到我了,那么我看不到任何GameCenter通知。但是,我 DO 是我的应用程序上的徽章!如果我只是简单地打开GameCenter应用本身,那么我也该轮到我了。因此,即使服务器上的数据已正确更新,即使操作系统级别的通知也没有收到。

我听说有消息说,GameCenter沙盒可能无法可靠地进行通知发送……但我真的不能冒险。我需要测试我的代码!

我尝试过的事情:

  • 确保我在真实设备上进行测试(没有模拟器)。我已经在4种真实设备上进行了测试,包括iPhones + iPad和iOS6 + iOS7。
  • 我每60秒执行一次NSAssert([GKTurnBasedEventHandler sharedTurnBasedEventHandler].delegate == self,以确保不丢失委托属性(每个问题:handleTurnEventForMatch:didBecomeActive: callbacks only arriving some of the time)
  • 再次检查是否已在设置
  • 中为该应用程序启用了推送通知
  • 检查iTunesConnect version完全等于我的CFBundleShortVersionString(info.plist)中的0.0.1,并且iTunesConnect将GameCenter显示为“已启用”游戏。我什至还将CFBundleVersion设置为相同的值,只是为了确保没有混乱的机会。
  • 在步骤3中使用版本#。我将它们分别设置为1.0.01.00.1等。我还使用NSLog将它们打印出来,以确保它们已正确复制到应用程序中。
  • 检查我是否正在使用从developer.apple.com下载的显式配置文件,并且XCode在Capabilities中的所有GameCenter步骤旁边均显示选中标记。 (例如,我使用“团队”是而不是;我已经登录到配置文件中心并创建了开发配置文件,下载了该文件,并在“调试设置的构建设置”中将其明确设置为Provisioning Profile)。
  • 明确请求推送通知权限。我能够成功检索(和使用) token ,因此APN服务似乎没有问题。
  • 我也尝试过...等待。我已经将调试器连接到了该设备。转牌过了10分钟后,没有代表被击中(我使用断点来确定)。


  • 更新
    这个问题很有趣:Sandbox Game Center Turn Event Notifications Not Consistent
    这导致我尝试使用[[GKLocalPlayer localPlayer] registerListener:self]而不是GKTurnBasedEventHandler委托方法。不幸的是,问题仍然没有解决。我什至尝试使用最低版本的SDK设置为7.0进行编译(因为这是7项以上的功能)。

    最佳答案

    我目前的看法是,GameCenter沙箱有问题,因为似乎很多人都遇到了问题。为了能够测试我的代码,我实际上编写了一些代码来轮询GameCenter并寻找更改。

    警告这是DUMB。我仅在DEBUG模式下启用了它,只是为了可以测试自己的handleTurnEventForMatch代码。就是说...它可以解决问题。

    该代码可以放入提供委托方法的同一类中。您需要做一些明显的逻辑修改。您应该从游戏逻辑中的适当位置调用onMultiplayerGameStartedonEndedMultiplayerTurn

    #if GAMEKIT_TURN_POLLING
    
    NSMutableDictionary *_wasLocalPlayersTurnMap = nil;
    
    - (void)pollGameCenter {
      if(!_wasLocalPlayersTurnMap) {
        _wasLocalPlayersTurnMap = [NSMutableDictionary new];
      }
      [AMGameData loadGames:^(NSArray *games) {
        NSInteger validGameCount = 0;
        for(AMGameData *gameData in games) {
          if(gameData.isSinglePlayer) {
            continue;
          }
          if(gameData.gameState != AMGameStatePlaying) {
            continue;
          }
          validGameCount++;
          if([_wasLocalPlayersTurnMap[gameData.name] boolValue]) {
            continue;
          }
          if(!gameData.isLocalPlayersTurn) {
            _wasLocalPlayersTurnMap[gameData.name] = @(NO);
            continue;
          }
          // Hey, it's now our turn!
          _wasLocalPlayersTurnMap[gameData.name] = @(YES);
          [self handleTurnEventForMatch:gameData.match didBecomeActive:NO];
        }
        if(validGameCount) {
          // Need to do this again later...
          [self delayedPollGameCenter];
        }
      }];
    }
    
    - (void)delayedPollGameCenter {
      [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(pollGameCenter) object:nil];
      [self performSelector:@selector(pollGameCenter) withObject:nil afterDelay:10];
    }
    
    - (void)onMultiplayerGameStarted {
      [self delayedPollGameCenter];
    }
    
    - (void)onEndedMultiplayerTurn:(AMGameData*)gameData {
      _wasLocalPlayersTurnMap[gameData.name] = @(NO);
      [self delayedPollGameCenter];
    }
    
    #else
    - (void)onMultiplayerGameStarted{}
    - (void)onEndedMultiplayerTurn:(AMGameData*)gameData {}
    #endif
    

    关于ios - GKTurnBasedEventHandler委托(delegate)未收到任何消息,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20906784/

    10-11 08:57