2012-10-13 137 views
26

Al usar el authenticateHandler en iOS 6, el centro de juegos no presentará la vista de inicio de sesión si el usuario lo cancela. Me doy cuenta de que el centro de juegos 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 regresar antes de que el centro de juegos presente el inicio de sesión incluso a través del comando authenticateHandler. ¿Alguna idea sobre cómo manejar este caso en iOS 6?iOS 6 Game Center authenticateHandler no puede iniciar sesión después de una cancelación

Funciona bien cuando se utiliza el método de authenticateWithCompletionHandler mayores:

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

La razón de que esto es importante para mi aplicación es que requiere el Centro de Juego para múltiples jugadores. La aplicación intenta autenticarse en el centro de juegos en el lanzamiento, pero si el usuario cancela no les pedimos que vuelvan a iniciarse para que no se les moleste. Lo que hacemos es mostrar un botón de inicio de sesión de Game Center si no están conectados cuando seleccionan varios jugadores. El botón de inicio de sesión obliga a iniciar sesión en el centro de juegos al llamar a authenticateWithCompletionHandler (y ahora configurando GKLocalPlayer.localPlayer.authenticateHandler nuevamente).

+1

Parece que ya lo está haciendo, pero al llamar a [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler: nil] hará que se llame de nuevo a authenticateHandler con un controlador de vista de autenticación. Este método está en desuso en iOS6. – Greg

+0

Estoy usando la llamada depreciada para que funcione, pero estoy buscando la forma "correcta" de hacerlo sin usar llamadas en desuso. Intenté configurar el nuevo GKLocalPlayer.localPlayer.authenticateHandler en cero y luego volver a mi controlador para ver si eso funcionaría, y obtuve una excepción al intentar establecerlo en cero.No intenté configurarlo en un controlador diferente para ver si eso activaría un inicio de sesión (que me pareció realmente raro) –

+0

He intentado cambiar el controlador a otro controlador, y eso tampoco desencadena una nueva apertura de diálogo de inicio de sesión . Publiqué en los foros de desarrolladores para ver si alguien tiene algún consejo, y volveré a publicar aquí si escucho algo. https://devforums.apple.com/message/744983 – Greg

Respuesta

2

Mejor utilice las comprobaciones de tiempo de ejecución (instancesRespondToSelector :) en lugar del preprocesador #if, para que pueda usar los métodos recomendados cuando estén disponibles y depreciados en otro lugar. De hecho, encontré que necesito distinguir tres casos antes de ajustar el controlador de invitación, como el controlador de autenticación también puede ser que consiga llamada 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, más casos deben distinguirse dentro del manejador de invitar, según matchForInvite: : es nuevo en iOS 6 y así evita una nueva ronda a través de los controladores de vista central 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éjame saber si esto ayuda.

+1

Las macros del preprocesador eran solo para depurar y mostrar el problema. El problema que tengo es que no se puede iniciar sesión con la API pública de iOS 6 si el usuario cancela el inicio de sesión inicial que muestra Game Center. La API pre-ios6 admite este comportamiento para restablecer el controlador. –

0

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

En la WWDC 2012 Vídeo: Sesión 516 - La integración de los juegos con Game Center [08:30] Se muestran en realidad código en el que llama a un método authenticate:

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

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

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

hace exactamente lo que quiere, pero no se puede utilizar porque ahora es privado.


También puede desencadenar 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 aconsejable hacer esto en código vivo.

Cuestiones relacionadas