I am working on a simple turn-based word game, and I'm having a difficult time figuring out how invitations are working. When user A invites user B to a game, I want user B to be able to see this game in my custom match interface (ie a screen where all of user B's games are listed). Things are fine if user B clicks on the notification when he is invited to a game, but I still want the game to be visible through my own interface if user B just navigates to the app on his own.
Whenever this match interface screen appears, I am using [GKTurnBasedMatch loadMatchesWithCompletionHandler:]
to get all of the local player's matches. With this, I would assume that user B would be able to see the match he has been invited to, but this new match doesn't show up. If I accept the invitation through the GKTurnBasedMatchmakerViewController
, the user enters the game as expected, but what makes this even more puzzling is that if I open up my GKTurnBasedMatchmakerViewController
and then cancel without accepting the invitation, a new match now shows up in my custom match interface, but it lacks the match data that was sent by user A.
To sum up, I am really just wondering how to properly display and accept GKTurnBasedMatch
invitations with a custom interface (rather than having to use GKTurnBasedMatchmakerViewController
). Thanks!
This question seems to be of interest to a couple people, so here's a rough approximation of what I ended up doing.
First of all, the reason new matches weren't showing up at all was just that I wasn't calling [GKTurnBasedMatch loadMatchesWithCompletionHandler:]
every time I wanted the view to refresh like I though I was. So no real issue there as I recall.
The real issue was the case where I was receiving and displaying the new GKTurnBasedMatch
, but none of the data (i.e. the opposing player's first move) was available. Essentially, [GKTurnBasedMatch loadMatchesWithCompletionHandler:]
doesn't seem to guarantee providing you with the most up-to-date GKTurnBasedMatch
objects available. To make sure the matches are up-to-date, I had to also call [match loadMatchDataWithCompletionHandler:]
, on each match returned by [GKTurnBasedMatch loadMatchesWithCompletionHandler:]
(where match
is one of those GKTurnBasedMatches). This returns the most current match data associated with that match as an NSData
object. I was then able to use this NSData
to make sure all the matches in my match table were refreshed to reflect the most recent changes in game center.
In short, use loadMatchDataWithCompletionHandler
on your GKTurnBasedMatch
objects to make sure their data is up to date.
UPDATE: now includes the actual answer for receiving invitations.
I have struggled with programmatically handling invites for turn-based matches for close to a week. I finally found the answer. I'm gonna super-highlight it because it took me so long to find:
Game Center treats turn-based invitations as turn events. They are not handled like other invitations.
Turn-based events are handled in this function in the GKLocalPlayerListener
protocol:
player(_ player: GKPlayer, receivedTurnEventFor match: GKTurnBasedMatch,
didBecomeActive: Bool)
When you recieve the match, check if you're invited to it, and presto. You've received an invitation.
BUT:
Through frustrating trial and error I have found some caveats, which hopefully can save you some serious time:
loadMatches
until it is their turn. Apparently Game Center does not actually involve any player on a match's invitation list in any way until it is their turn.acceptInvite(...)
directly on that match. So if playerJake inspected the matches retrieved by loadMatches
, and was able to detect that matchFoo still had an open invitation, playerJake has to call matchFoo.acceptInvite( /* ...completion handler stuff here... */)
, and then happy playerJake is off and running.From this you should be able to get your own programmatic matching system to work. Best of luck, and I mean it!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With