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

后端 未结 4 1555
长情又很酷
长情又很酷 2020-12-13 22:14

Has anyone noticed any changes to turn based match notifications since updating to iOS8.3? In my app when I call endTurnWithNextParticipants, prior to the upgrade, this was

4条回答
  •  盖世英雄少女心
    2020-12-13 22:59

    Updated answer:

    My original idea, below, turns out to not be reliable. You cannot count on the saveCurrentTurnWithMatchData to send timely notifications. It works most of the time, but at least 10% of the time, it fails to send a notifications as well. Of all the ideas posted here, the only thing I have found that works 100% reliably is to set up a timer loop on the non-active machines and continuously watch until you become active.

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

    Original Answer:

    So, I have a work around that is kludgy but looks promising. Note that, per my comment above, the subsequent players still receive events after the current player executes saveCurrentTurnWithMatchData. So I use that send my own custom signal:

    1. I added a string to my matchData for the "next player's ID."

    2. Right before I call endTurnWithNextParticipants, I set that string to the ID of the next player in the rotation.

    3. I call saveCurrentTurnWithMatchData

    4. I moved the call to endTurnWithNextParticipants inside saveCurrentTurnWithMatchData's completion handler, to ensure it doesn't fire until after saveCurrentTurnWithMatchData.

    5. For the purposes of this work around, I added the GKTurnBasedEventHandlerDelegate to my code. handleTurnEventForMatch is broken in 8.3 too, but I consolidated all of my workaround code there and didn't have to make changes to receivedTurnEventForMatch

    6. In handleTurnEventForMatch, I check to see if the "next player" string is me. If so, I assume that the current player just saved the game in step 2, signalling his intention to pass the turn to me.

    7. I start a timer loop, reloading the match data until it shows that I have become the active player.

    8. When I see that I am now the active player, I reset my custom next player string to nil and I manually call receivedTurnEventForMatch passing it the match data I just downloaded.

    To summarize, player1 sends an extra saveTurn event to signal that he intends to end the turn. When player2 receives that signal, he re-reads the match data until it shows that he has become active. Then he calls his own receivedTurnEventForMatch with the updated match data, allowing the turn to proceed.

    I haven't gotten through all my scenarios yet, but it looks like this is going to work.

提交回复
热议问题