I'm replying almost two years later but maybe this will help someone.
In trying to diagnose this issue I observed that a failure to connect can happen one of two ways:
- Each handset is searching for a match but they never connect, and neither is ever given a GKMatch object.
- Each handset is searching for a match and only one of them is given an empty GKMatch object, and the empty seat in that match is never filled.
I suppose it's possible for both handsets to be given an empty match, and neither of them connect to each other, but I've never seen that.
What I noted was that, if both handsets somehow got stuck in the "never gonna get any response at all" cycle, you could wait around forever and nothing would happen, but if one handset was given a GKMatch, there was still a chance that a connection would be made, if I kept both handsets searching long enough. So my thought was that I needed something that would reset a match search if nothing happened after a period of time, but that would extended that period of time if there was an empty GKMatch.
What I ended up implementing worked like this:
- upon requesting a match, create an action dispatched to the background queue (very important that it's the background queue!) that checks the status of the match request every 15 seconds (by checking if a GKMatch has been assigned to an optional property I created in my Game Center Handler class).
- If there is no match, I cancel the match request and in the completion handler of the cancellation order, start a new search.
- If there is a match but the empty seat has not been filled, set a second dispatch action to make this inspection again after another 15 seconds.
- If, in that inspection (after a total of 30 seconds have passed since search started) there's still an unfilled empty match, cancel the match request and start a new one just like in step 2.
The downside of this is that it can take a long time. In my testing making the connection inspection happen any sooner than 15 seconds resulted in many successful matches getting cancelled (which can happen if the successful connection is made between the time the cancellation request is sent and the time that the completion handler of that request is activated). For some reason, though, the 15-second-period seemed to avoid that problem. It's a long wait, though, and that frustrates me.
The upside is that ever since implementing this system I have never failed to successfully connect two handsets looking for a game, and that really makes me happy.