iosswiftgkturnbasedmatch

How to get notified when a player "Remove" a match in progress from GKTurnBasedMatchmakerViewController


I am using the default GKTurnBasedMatchmakerViewController. A player can "Remove" a match in progress by sliding the match cell to the left and then tapping the red "Remove" button. But this does not notify the other player that the first one has removed (and quit as well) the match. The other one continues to wait another player to join the match and make a turn. But this is against the logic of my game. I want to end the match as soon as any player quits the match or removes it. Is there any way to receive any kind of callback or set matchOutcome for player who wants to remove the match? Thanks for help.


Solution

  • This has long been a weak spot in GKTurnBasedMatches. Matches may be updated outside of your game, through the match maker view controller and (in <= IOS9) the Game Center app, frequently creating unrecoverable scenarios.

    Player swipe to remove match describes using this same issue (but cites the now-removed Game Center app) as an exploit to avoid incurring a loss. I posted a partial work-around there, and a similar approach will help mitigate your situation, too:

    1. Any time you receive an invite, join a match or create a match, store the matchID locally.
    2. When the game starts, call loadMatchesWithCompletionHandler to pull all the matches the local player knows about. Matches that the local player deleted "outside" your app will be (appropriately) missing from the server's list.
    3. Even though they deleted the match from their list, they can still load the specific match using loadMatchWithID. So, for each "missing" match, call loadMatchWithID using the matchID you stored locally, get the match object, and then call either participantQuitInTurnWithOutcome, participantQuitOutOfTurnWithOutcome, or declineInviteWithCompletionHandler based on the player's status in the deleted match.
    4. Quitting / Declining will send a notification and/or pass the turn to the other player.

    Although not ideal, as long as the "deleter" starts the game again, you have a chance to evaluate all the games and force a clean exit from the matches they deleted. Calling either of the participantQuit functions will send a notification (and/or pass the the turn) to the other player.

    This work around won't work, though, if the "deleter" never starts the game again. In that scenario, all the other player can do is eventually leave the match themselves if they haven't seen any progress after some set time interval.