ios6 game-center

ios6 - iOS 6 Game Center authenticateHandler no puede iniciar sesión después de una cancelación



game-center (2)

No creo que esto sea posible en iOS 6.0. Hubo llamadas a la API para hacer esto en las primeras versiones de SDK que se eliminaron antes del lanzamiento.

En la WWDC 2012 Video: Sesión 516 - Integración de tus juegos con Game Center [8:30] En realidad, muestran el código donde llamas a un método de authenticate :

GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer]; localPlayer.authenticationHandler = //handle the callback... [localPlayer authenticate];

Este método ahora es API privado, pero puede verlo en acción llamando a:

[[GKLocalPlayer localPlayer] performSelector:@selector(_authenticate)];

Hace exactamente lo que quiere, pero no puede usarse porque ahora es privado.

También puede activar el proceso de autenticación mediante la publicación de la notificación UIApplicationWillEnterForegroundNotification :

[[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillEnterForegroundNotification object:[UIApplication sharedApplication]];

Supongo que sería desaconsejable hacer esto en código en vivo.

Cuando se utiliza el authenticateHandler en iOS 6, Game Center no presentará la vista de inicio de sesión si el usuario la cancela. Me doy cuenta de que Game Center bloqueará automáticamente una aplicación después de 3 intentos de cancelación, pero estoy hablando de solo 2 intentos. Si cancelan el inicio de sesión, tienen que abandonar la aplicación y volver antes de que Game Center presente el inicio de sesión, incluso a través de AuthenticHandler se está configurando nuevamente. ¿Alguna idea sobre cómo manejar este caso en iOS 6?

Funciona bien cuando se usa el método más antiguo authenticateWithCompletionHandler:

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0 GKLocalPlayer.localPlayer.authenticateHandler = authenticateLocalPlayerCompleteExtended; #else [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:authenticateLocalPlayerComplete]; #endif

La razón por la que esto es importante para mi aplicación es que requiere Game Center para varios jugadores. La aplicación intenta autenticarse en el centro de juego en el lanzamiento, pero si el usuario cancela, no le pedimos que lo haga de nuevo para que no se molesten. Lo que hacemos es mostrar un botón de inicio de sesión en Game Center si no están conectados cuando seleccionan multijugador. El botón de inicio de sesión fuerza el inicio de sesión del centro de juego llamando a authenticateWithCompletionHandler (y ahora configurando GKLocalPlayer.localPlayer.authenticateHandler de nuevo).


Utilice mejor las comprobaciones en tiempo de ejecución (instanceRespondToSelector :) en lugar de las instrucciones #if del preprocesador, de modo que pueda usar los métodos recomendados cuando estén disponibles y los depreciados en otros lugares. De hecho, encontré que necesito distinguir tres casos antes de configurar el controlador de invitaciones, ya que el controlador de autenticación también podría llamarse con un controlador de vista nula:

-(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]; }]; } }

Sin embargo, se deben distinguir más casos dentro del controlador de invitaciones, ya que matchForInvite :: también es nuevo en iOS6 y evita otra ronda a través de los controladores de la vista del centro de juego:

-(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 } }; } }

Déjeme saber si esto ayuda.