The following delegate method is called by gameKit, when a person accepts an invitation
-(void)player:(GKPlayer *)player didAcceptInvite:(GKInvite *)invite
{
NSLog(@"%@ accepted invite",player.playerID);
RIYGameNavigationController *root = (RIYGameNavigationController*)[[[UIApplication sharedApplication]delegate]window].rootViewController;
[root popToRootViewControllerAnimated:YES];
GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc]initWithInvite:invite];
mmvc.matchmakerDelegate = root.viewControllers[0];
[[[[[UIApplication sharedApplication]delegate]window]rootViewController]presentViewController:mmvc animated:YES completion:nil];
}
This "works" when the user is not already presenting a GKMatchmakerViewController
.
This does not work if the user is already using the GKMatchmakerViewController when the invite comes in (Eg: When the user is already trying to find a match). If this is the case, when the invite comes in, I get the following warning, and the controller with the invite is not presented (since there is already a matchmakercontroller being presented). As a result, the user cannot respond to an invite. (Nothing happens).
Warning: Attempt to present <GKMatchmakerViewController: 0x1458a250> on <RIYGameNavigationController: 0x1461f190> which is already presenting <GKMatchmakerViewController: 0x1465fcb0>
In iOS6, one could get around this by doing:
if([topLevelViewController modalViewController] != nil)
[topLevelViewController dismissModalViewControllerAnimated:NO];
and then creating the GKMatchmakerViewController
. dismissModalViewControllerAnimated:
has been deprecated in iOS6. It is suggested to use dissmissViewControllerAnimated:completion:
instead, but it doesn't work for me. This is what I tried:
-(void)player:(GKPlayer *)player didAcceptInvite:(GKInvite *)invite
{
NSLog(@"%@ accepted invite",player.playerID);
RIYGameNavigationController *root = (RIYGameNavigationController*)[[[UIApplication sharedApplication]delegate]window].rootViewController;
[root popToRootViewControllerAnimated:YES];
if ([[root presentedViewController]class] == [GKMatchmakerViewController class]) {
[root dismissViewControllerAnimated:YES completion:nil];
}
GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc]initWithInvite:invite];
mmvc.matchmakerDelegate = root.viewControllers[0];
[[[[[UIApplication sharedApplication]delegate]window]rootViewController]presentViewController:mmvc animated:YES completion:nil];
}
The if block gets entered, but the existing GKMatchmakerViewController is not dismissed, and the new one does not show up. If I put a break point in the if statement, when I "continue" after the break, the view controller is dismissed, but the new one does not pop up.
How can I get this working?
I got around this by presenting the view in the completion block.
- (void)presentMatchmakerViewControllerWithInvite:(GKInvite *)invite
{
RIYGameNavigationController *root = (RIYGameNavigationController*)[[[UIApplication sharedApplication]delegate]window].rootViewController;
GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc]initWithInvite:invite];
mmvc.matchmakerDelegate = root.viewControllers[0];
[[[[[UIApplication sharedApplication]delegate]window]rootViewController]presentViewController:mmvc animated:YES completion:nil];
}
-(void)player:(GKPlayer *)player didAcceptInvite:(GKInvite *)invite
{
NSLog(@"%@ accepted invite",player.playerID);
RIYGameNavigationController *root = (RIYGameNavigationController*)[[[UIApplication sharedApplication]delegate]window].rootViewController;
[root popToRootViewControllerAnimated:YES];
if ([[root presentedViewController]class] == [GKMatchmakerViewController class]) {
[root dismissViewControllerAnimated:YES completion:^{
[self presentMatchmakerViewControllerWithInvite:invite];
}];
}
else
{
[self presentMatchmakerViewControllerWithInvite:invite];
}
}
It seems to work, but I feel it is clumsy. If someone has a better answer I will mark that as the correct one