In iOS 9 Apple deprecated the public func turnBasedMatchmakerViewController(_ viewController: GKTurnBasedMatchmakerViewController, didFind match: GKTurnBasedMatch) method of the GKTurnBasedMatchmakerViewControllerDelegate.

Apple's direction is to use the func player(_ player: GKPlayer, receivedTurnEventFor match: GKTurnBasedMatch, didBecomeActive: Bool) method of GKLocalPlayerListener.

Using only receivedTurnEventFor match leads to the following scenario:

  1. User taps + which displays a GKTurnBasedMatchmakerViewController.
  2. User taps Play Now and Game Center will search for a match.
  3. Game Center will return a match with empty matchData (a new match), or place the user into a match in progress — and the game is informed of this through receivedTurnEventFor match.

While it is simple enough to determine if a new match has been created (using matchData), there doesn't appear to be a way to determine if a match has been found vs a match being updated as all events flow through receivedTurnEventFor match.

My question is this:

When using GKLocalPlayerListener's receivedTurnEventFor match method, is there a way to determine if the turn event is the result of a matchmaking find?

2

There are 2 best solutions below

0
On

I don't think game center will help you on this one. It looks like yet another ambiguous call to the overloaded receivedTurnEventForMatch function. But, I believe you can manage this yourself since you know the originating player always sees the match first, before any of the other participants.

Looks like there are four cases here:

The player creates a new match with at least 1 automatch participant: you can detect this because the participants will be in "matching" status when you receive the new match. In this case, as originator, you can set flags in the match data that indicates which players have invites and which are automatches.

The player creates a new match with invites: In this case, all of the participants should be set in the newly received match. Again, you can set flags in the match data that subsequent players can read.

The player joins a match that was created as an automatch: If you support only 2 players, at the time player2 receives this match both playerIDs will be set. If you support more, there's an (unreliable) chance that some slots will still be set to automatch, but that's not very helpful. If the originating player set flags in the match data indicating which players were invited vs automatch slots, though, this player can determine their own status.

The player joins a match had one or more invitations: Same as the prior situation. The joining player can't determine anything useful from game center, and will rely on data added to the match by the originating player.

3
On

There are four cases: 1. You join a new match and it's your turn (you are creator of the match) 2. You join a new match and it's other player turn (you found the match) 3. You join an exising match and it's your turn 4. You join an existing match and it's other player turn. Cases 3 and 4 could be when you switch between matches or rejoin a match.

You can check match.currentPatriticant and lastTurnDate properties to determine which case takes place.

If a player just create a new match (receivedTurnEventFor is called as a result of matchmaking) the match.participants[0].lastTurnDate is nil and match.currentParticipant?.player?.playerID is equal GKLocalPlayer.localPlayer().playerID (case 1).

If you join an existing match: match.participants[0].lastTurnDate is nil and match.currentParticipant?.player?.playerID is NOT equal GKLocalPlayer.localPlayer().playerID (you joined a new match, but other player is in a turn - case 2)

Do determine unambiguously cases 3 and 4 you can check lastTurnDate of all participant and compare local player with current player.