I'm trying to implement Game Center invites in a 2-person realtime game. Since invites are not supported in the simulator, I'm testing this on one device running iOS5 and a second one running iOS6 (this is done on purpose).
If I'm using the old-fashioned built-in GKMatchmakerViewController
UI on either device to initiate the invite, it works fine both ways - when the iOS5 device initiates the invite as well as when the iOS6 device initiates it.
However, in iOS6 I want to use my own UI to select the player to invite, so I'm using GKMatchRequest
to programmatically issue the invite, setting the playersToInvite
attribute.
The problem is, the other (iOS5) device gets the push notification, launches the application, runs the [GKMatchmaker sharedMatchmaker].inviteHandler
, shows the Game Center UI with the invite details, but even when the iOS6 device sends a finishMatchmakingForMatch
request - the iOS5 device doesn't proceed any further. No other handler / delegate is called on the iOS5 machine, no GKMatch
object is returned, and it continues to show the Game Center UI with both players marked as "Ready" and with a message saying "Waiting for [iOS6 player] to start the game". The only button on this UI is a Cancel button.
Here's the code snippet that sends the invitation on the iOS6 machine:
GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
request.minPlayers = 2;
request.maxPlayers = 2;
request.playersToInvite = [NSArray arrayWithObject:playerID];
request.inviteMessage = message;
request.inviteeResponseHandler = ^(NSString *playerID, GKInviteeResponse response)
{
if (response == GKInviteeResponseAccepted)
[[GKMatchmaker sharedMatchmaker] finishMatchmakingForMatch:self.match];
};
[[GKMatchmaker sharedMatchmaker] findMatchForRequest:request withCompletionHandler:^(GKMatch *match, NSError *error)
{
... [whatever]
}];
And here's the code snippet for the invite handler on the iOS5 machine:
[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite)
{
if (acceptedInvite)
{
GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite] autorelease];
mmvc.matchmakerDelegate = self;
[navController presentModalViewController:mmvc animated:YES];
});
else if (playersToInvite)
{
... [whatever]
}
}
The sequence is as follows:
- iOS6 sends a
findMatchForRequest
request with the iOS5 player id. - A push notification is shown on the iOS5 machine.
- The application is launched on the iOS5 machine and the
inviteHandler
is called. - The
GKMatchmakerViewController
is shown on the iOS5 machine with the invite details, and the iOS6 user has a spinning "Connecting" status. - The
inviteeResponseHandler
on the iOS6 machine is called and sends afinishMatchmakingForMatch
request. - The status of the iOS6 user in the iOS5 Game Center screen changes from spinning "Connecting" to "Ready", and at this point both players are marked as "Ready".
- The iOS6 machine gets a
match: player: didChangeState:
callback, showing the iOS5 player asGKPlayerStateConnected
, so as far as the iOS6 machine is concerned the match process is finished and the game can begin. - Nothing whatsoever happens from now on on the iOS5 machine. It is stuck with "Waiting for [iOS6 user] to start the game" until it is cancelled by a timeout. It never receives any
GKMatch
object at any point, so it cannot start the game.
Since things work fine if I use the standard Game Center UI on the iOS6 machine rather than a programmable invite, it means that the standard UI must do something more to tell the other machine that the game has to start. However, I browsed through all the relevant Game Center objects and couldn't find anything else to send.
I should mention again that the reverse configuration (iOS5 initiating the invite using the standard UI) works fine on both machines.
Help, anyone?