When using the authenticateHandler in iOS 6, game center won\'t present the login view if the user cancels it. I realize game center will auto lockout an app after 3 cancel
Better use runtime checks (instancesRespondToSelector:) instead of preprocessor #if statements, so that you can use recommended methods where they are available and depreciated ones elsewhere. I actually found I need to distinguish three cases before setting the invite handler, as the authentication handler might also get called with a nil view controller:
-(void)authenticateLocalPlayer
{
if ([[GKLocalPlayer class] instancesRespondToSelector:@selector(setAuthenticateHandler:)]) {
[[GKLocalPlayer localPlayer] setAuthenticateHandler:^(UIViewController *gameCenterLoginViewController, NSError *error) {
if (gameCenterLoginViewController) {
[self.presentedViewController presentViewController:gameCenterLoginViewController
animated:YES
completion:^{
[self setInviteHandlerIfAuthenticated];
}];
} else {
[self setInviteHandlerIfAuthenticated];
}
}];
} else { // alternative for iOS < 6
[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error) {
[self setInviteHandlerIfAuthenticated];
}];
}
}
Yet more cases must be distinguished within the invite handler, as matchForInvite:: is new in iOS6 as well and avoids yet another round through game center view controllers:
-(void)setInviteHandlerIfAuthenticated
{
if ([GKLocalPlayer localPlayer].isAuthenticated) {
[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) {
if (acceptedInvite) {
if ([GKMatchmaker instancesRespondToSelector:@selector(matchForInvite:completionHandler:)]) {
[self showInfoAnimating:YES completion:NULL];
[[GKMatchmaker sharedMatchmaker] matchForInvite:acceptedInvite
completionHandler:^(GKMatch *match, NSError *error) {
// ... handle invited match
}];
} else {
// alternative for iOS < 6
GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite] autorelease];
mmvc.matchmakerDelegate = self;
// ... present mmvc appropriately
// ... handle invited match found in delegate method matchmakerViewController:didFindMatch:
}
} else if (playersToInvite) {
// ... handle match initiated through game center
}
};
}
}
Let me know if this helps.
I dont' think this is possible in iOS 6.0. There were API calls to do this in the early SDK builds that were removed before release.
In the WWDC 2012 Video: Session 516 - Integrating Your Games with Game Center [8:30] They actually show code where you call an authenticate method:
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticationHandler = //handle the callback...
[localPlayer authenticate];
This method is now private API but you can see it in action by calling:
[[GKLocalPlayer localPlayer] performSelector:@selector(_authenticate)];
It does exactly what you want, but can't be used because it's now private.
You can also trigger the authentication process by posting the UIApplicationWillEnterForegroundNotification notification:
[[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillEnterForegroundNotification object:[UIApplication sharedApplication]];
I assume it would be unadvisable to do this in live code.