receivedTurnEventForMatch giving stale data

In my turn-based game, I receive GKListener event receivedTurnEventForMatch and decode the match.matchData. On occasion, the matchData is clearly stale and is from the previous turn. If I call the MatchMaker ViewController up and select that same match, the data is not stale, so it's not a matter of not calling endTurn.

I have tried both loadMatchWithID and loadMatchesWithCompletionHandler after receiving the receivedTurnEventForMatch, but the data is still stale.

Advice?

Answered by DTS Engineer in 884963022

What you're seeing is a propagation timing issue — the push notification that triggers receivedTurnEventForMatch can arrive before the updated match data is fully available on the server. That's why both the GKTurnBasedMatch delivered with the callback and a subsequent loadMatch(withID:) return stale data.

A fixed delay is fragile because the propagation time varies with server load and network conditions. A more robust approach is to retry loadMatch(withID:) with a comparison check — for example, if the match still shows the previous participant as the current player, or the matchData hasn't changed from your last known state, wait briefly and retry. Something like an exponential backoff starting at 1 second, up to a reasonable cap, gives the server time to propagate without relying on a magic number.

If you haven't already, please file a feedback report with Feedback Assistant and include your sample project. The behavior you're describing — where loadMatch(withID:) returns stale data even after the turn event fires — is worth tracking. Please post the feedback number here so we can follow up.

At the moment, my workaround is to call loadMatchWithID after a 2-second delay if the match received by receivedTurnEventForMatch shows that the current participant is not the localPlayer.

Two-second delay seemed to work for awhile - I even saw it trigger the loadMatchWithID because it got stale data. Then, I even got stale data on a loadMatchWithID. Not sure how to proceed with this.

I tried gemini-recommended strategy of calling loadMatchesWithCompletionHandler (all matches) - made no difference. A 5-second delay seems to solve the problem, at least for now.

What you're seeing is a propagation timing issue — the push notification that triggers receivedTurnEventForMatch can arrive before the updated match data is fully available on the server. That's why both the GKTurnBasedMatch delivered with the callback and a subsequent loadMatch(withID:) return stale data.

A fixed delay is fragile because the propagation time varies with server load and network conditions. A more robust approach is to retry loadMatch(withID:) with a comparison check — for example, if the match still shows the previous participant as the current player, or the matchData hasn't changed from your last known state, wait briefly and retry. Something like an exponential backoff starting at 1 second, up to a reasonable cap, gives the server time to propagate without relying on a magic number.

If you haven't already, please file a feedback report with Feedback Assistant and include your sample project. The behavior you're describing — where loadMatch(withID:) returns stale data even after the turn event fires — is worth tracking. Please post the feedback number here so we can follow up.

receivedTurnEventForMatch giving stale data
 
 
Q