Handle invitation to GKTurnBasedMatch without game center view controllers

ぐ巨炮叔叔 提交于 2019-12-04 08:18:53

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:

  1. It just plain doesn't always work. Believe it or not, Game Center is unreliable. This means you need a back-up system that reviews your local player's open matches and searches them for new invitations. That itself pertains to caveat #2.
  2. A player that is invited to a match (for instance say playerJake is invited to matchFoo) will not actually get that invitation nor see that match in the matches returned by 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.
  3. If you can identify a match you're invited to, but haven't responded to, you must call 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!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!