1

我遇到了一个非常古老的问题,这里已经讨论过很多次了。尽管多次讨论这个问题,但我没有找到可以接受的解决方案,所以我决定再次提出这个问题。

所以,问题。我正在尝试测试回合制比赛。我为此使用了两个真实的设备。我打开第一台设备,匹配数据更新没有错误(我肯定知道),但有时第二台设备没有收到任何通知,似乎第一台设备仍在转弯。有时它会按预期工作。

换句话说player(_:receivedTurnEventFor:didBecomeActive),有时不会调用方法。但是,如果我关闭第二台设备上的应用程序,重新打开它并加入现有的比赛,一切正常。据我了解,这是众所周知的 Game Center Sandbox 问题,但在我尝试测试应用程序时它让我发疯。有谁知道如何解决?或者也许有一个最佳实践如何使用这种奇怪的沙盒行为来运行和测试应用程序?

更新。Thunk 提出的方法是一种解决方案。我用 Swift 重写了它并修改为符合我的游戏逻辑。首先,我定义了全局变量 var gcBugTimer: Timer

endTurn(withNextParticipants:turnTimeOut:match:completionHan‌​dler:)完成处理程序中:

let interval = 3.0
self.gcBugTimer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(self.isMatchActive), userInfo: nil, repeats: true)
self.gcBugTimer.tolerance = 1.0

上面的代码也应该被调用,以防玩家对新的比赛和其他玩家感到高兴。

然后定时器方法:

func isMatchActive() {
  // currentMatch - global variable contains information about current match 
  GKTurnBasedMatch.load(withID: currentMatch.matchID!) { (match, error) in
    if match != nil {
      let participant = match?.currentParticipant
      let localPlayer = GKLocalPlayer.localPlayer()
      if localPlayer.playerID == participant?.player?.playerID {
        self.player(localPlayer, receivedTurnEventFor: match!, didBecomeActive: false)
      }
    } else {
      print(error?.localizedDescription ?? "")
    }
  }
}

我在开头添加了以下代码player(_:receivedTurnEventFor:didBecomeActive)

if gcBugTimer != nil && gcBugTimer.isValid {
  gcBugTimer.invalidate()
}
4

1 回答 1

1

我发现唯一可靠的解决方案是在等待轮到我时手动重新检查我的状态。在完成处理程序中,endTurnWithNextParticipants我设置了一个计时器以不断重新加载匹配数据。我检查了是否localPlayer已成为活跃玩家。如果是这样,那么我打电话给receivedTurnForEvent自己,否则,我重复计时器。像这样:

endTurnWithNextParticipants完成处理程序中:

       float dTime = 60.0;     //messages sometimes fail in IOS8.4
        if (SYSTEM_VERSION_EQUAL_TO(@"8.3") )
        {
            dTime = 5.0;        //messages always fail in IOS8.3
        }
        IOS8BugTimer = [NSTimer scheduledTimerWithTimeInterval:dTime
                                                             target:gameKitHelper
                                                           selector:@selector(isMatchActive:)
                                                           userInfo:theMatch.matchID
                                                            repeats:NO];

在 gameKitHelper:isMatchActive:

-(void)isMatchActive:(NSTimer *)timer
{

    NSString *matchID = (NSString *)timer.userInfo;
    [GKTurnBasedMatch loadMatchWithID:matchID withCompletionHandler:^(GKTurnBasedMatch *match, NSError *error)
    {
        GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
        GKTurnBasedParticipant *currentParticipant = match.currentParticipant;

        if ([localPlayer.playerID isEqualToString:currentParticipant.player.playerID])
        {
            //we have become active. Call the event handler like it's supposed to be called
            [self player:localPlayer receivedTurnEventForMatch:match didBecomeActive:false];
        }
        else
        {

            //we are still waiting to become active. Check back soon
            float dTime = 60.0;

            if (SYSTEM_VERSION_EQUAL_TO(@"8.3") )
            {
                dTime = 5.0;
            }

            gameController.IOS8BugTimer = [NSTimer scheduledTimerWithTimeInterval:dTime
                                                                       target:self
                                                                     selector:@selector(isMatchActive:)
                                                                     userInfo:matchID
                                                                      repeats:NO];
        }
    }];

}
于 2017-02-09T04:36:09.190 回答