endTurnWithNextParticipants 在更新到 iOS 8.3 和 swift 1.2 后不会触发 receivedTurnEventForMatch

endTurnWithNextParticipants doesn't trigger receivedTurnEventForMatch after update to iOS 8.3 and swift 1.2

自更新到 iOS8.3 以来,有没有人注意到回合制比赛通知有任何变化?在我的应用程序中,当我在升级之前调用 endTurnWithNextParticipants 时,这会导致向对手发送通知,这将触发在他们的设备上调用 receivedTurnEventForMatch,但现在不再是这种情况。当对手终止应用程序并重新启动时,他们可以看到轮到他们了,因此游戏中心的比赛已根据参与顺序正确更新,但这似乎不再动态生效。

还有其他人看到了吗?我希望这只是游戏中心沙盒环境中的一个临时故障。

我已经向 apple 提出了一个错误报告,看看它是否真的是一个错误,或者 iOS8.3 中是否存在一些未记录的行为变化,我们需要了解。

我有同样的问题..我有多个设备,8.3 的设备不会触发 receivedTurnEventForMatch 事件,但是当应用程序在后台运行时,关于转向的横幅通知将照常出现。仅当应用程序处于前台时才会出现问题。

另一方面,8.2 或 8.1.3 的设备在任何情况下都运行良好。所以这肯定是8.3造成的。 8.3 的设备也在 Xcode 中标记为不合格。你也会这样吗?

更新的答案:

我原来的想法,下面,结果证明不靠谱。您不能指望 saveCurrentTurnWithMatchData 及时发送通知。它大部分时间都有效,但至少有 10% 的时间也无法发送通知。在此处发布的所有想法中,我发现 唯一 的方法可以 100% 可靠地工作,即在非活动机器上设置一个计时器循环并持续观察,直到你变得活跃。

-(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 = 5.0;
            gameController.IOS8BugTimer = [NSTimer scheduledTimerWithTimeInterval:dTime
                                                                          target:self
                                                                     selector:@selector(isMatchActive:)
                                                                     userInfo:matchID
                                                                      repeats:NO];
         }
     }];
}

原答案:

所以,我有一个解决方法,它虽然笨拙但看起来很有前途。请注意,根据我上面的评论,后续玩家在当前玩家执行 saveCurrentTurnWithMatchData 后仍会收到事件。所以我使用它发送我自己的自定义信号:

  1. 我在 "next player's ID."

  2. 的 matchData 中添加了一个字符串
  3. 就在调用 endTurnWithNextParticipants 之前,我将该字符串设置为轮换中下一位玩家的 ID。

  4. 我调用saveCurrentTurnWithMatchData

  5. 我将对 endTurnWithNextParticipants 的调用移到了 saveCurrentTurnWithMatchData 的完成处理程序中,以确保它不会触发直到 saveCurrentTurnWithMatchData.

  6. 之后
  7. 为了解决此问题,我将 GKTurnBasedEventHandlerDelegate 添加到我的代码中。 handleTurnEventForMatch 在 8.3 中也被破坏了,但是我在那里整合了我所有的解决方法代码并且不必对 receivedTurnEventForMatch

  8. handleTurnEventForMatch中,我检查"next player"字符串是否是我。如果是这样,我假设当前玩家刚刚在步骤 2 中保存了游戏,表示他打算将转弯交给我。

  9. 我开始计时循环,重新加载比赛数据,直到显示我已成为活跃玩家。

  10. 当我看到我现在是活跃玩家时,我将我的自定义下一个玩家字符串重置为 nil 并手动调用 receivedTurnEventForMatch 将比赛数据传递给它我刚下载。

总而言之,玩家 1 发送了一个额外的 saveTurn 事件来表示他打算结束回合。当 player2 收到该信号时,他重新读取比赛数据,直到它显示他已激活。然后他用更新的比赛数据调用他自己的 receivedTurnEventForMatch,允许回合继续进行。

我还没有完成所有场景,但看起来这会奏效。

更新: Apple 已回复错误报告:

Please verify this issue with iOS 8.4 beta 4 (Build: 12H4125a) and update your bug report at http://bugreport.apple.com/ with your results.

iOS 8.4 beta 4 (Build: 12H4125a) https://developer.apple.com/ios/download/ Posted: June 9th, 2015

很遗憾,我无法在我的设备上安装 iOS 8.4 beta 4,也无法告诉您它现在是否已修复。如果你们中的任何人有这个机会,请分享。


我已就此问题向 Apple 提交错误报告,并会在他们回复后post在此处更新。

我的回合制游戏有这个解决方法。看起来很糟糕,但它又开始工作了——也许对你有帮助。

- (void)sendGameStateWith:(NSMutableDictionary *)data
{
    if (self.match) {
        NSData *matchdata = [NSKeyedArchiver archivedDataWithRootObject:data];

        GKTurnBasedParticipant *opponent = [self.match.participants objectAtIndex:0];
        GKTurnBasedParticipant *localPlayer = [self.match.participants objectAtIndex:1];
        if ([self.localPlayer.playerID isEqualToString:opponent.playerID]) {
            opponent = [self.match.participants objectAtIndex:1];
            localPlayer = [self.match.participants objectAtIndex:0];
        }

        // HINT: Remove this workaround when Apple has fixed it. 
        [self.match saveCurrentTurnWithMatchData:matchdata completionHandler:^(NSError *error) {
            if (error) {
                NSLog(@"Error on saveCurrentTurnWithMatchData");
                [self sendGameStateWith:data];

            } else {
                [self.match endTurnWithNextParticipants:[NSArray arrayWithObjects:opponent, localPlayer, nil] turnTimeout:turnTimeout matchData:matchdata completionHandler:^(NSError *error) {
                    if (error) {
                        NSLog(@"Error: Send Game Center state");
                    } else {
                        NSLog(@"Sent Game Center state");
                    }
                }];
            }
        }];
    }
}

我们在 iOS 8.3 下遇到了同样的问题,它已在昨天发布的 iOS 8.4 中得到修复。

更新 1

在我们的案例中,@appsunited 的解决方法确实解决了 iOS 8.3 的问题,并且不再需要 iOS 8.4。

我们测试了沙盒和我们当前的应用商店版本。并与 iPad 3 iOS 7.1.2 对抗另一个 iPad 3 iOS 8.3 和昨天 8.4.