2012-09-25 18 views
6

Mi aplicación mantiene un registro de si se ha autenticado correctamente con Game Center. Cuando comienza un nuevo juego o cuando el usuario mira la lista de puntajes, si un jugador local no se ha autenticado con éxito y si la aplicación no está en el medio de tratar de autenticar a un usuario en ese momento, intenta de nuevo .GKLocalPlayer Auth Crash en iOS6 con error de transición modal

(¿Por qué? En caso de que haya movido de una zona de exclusión de red a una zona de la red.)

Desafortunadamente, bajo iOS6/XCode 4.5, que ha comenzado estrellarse. O al menos parece que en ciertas circunstancias limitadas: cuando un usuario no puede iniciar sesión con una contraseña incorrecta y/o una cuenta que no existe. En un inicio de sesión exitoso, todo está bien.

Después de ese inicio de sesión fallido, cuando voy y hago algo que causa un cheque reauth que ocurra me sale esto:

2012-09-25 15: 54: 47.829 APP NOMBRE [1493: 907] * fracaso aserción en - [UIWindowController transición: fromViewController: toViewController: objetivo: didEndSelector:], /SourceCache/UIKit/UIKit-2372/UIWindowController.m:211

Entonces este se bloquea en realidad:

2012-09-25 15: 55: 25.569 APP NOMBRE [1493: 907] * Terminación de aplicación debido a excepción no detectada 'NSInternalInconsistencyException', razón: 'El intento de iniciar una transición modal de la < GKModalRootViewController : 0x1cd8b2a0 > a < GKHostedAuthenticateViewController: 0x1e31a350 > mientras que una transición es ya en progreso. Esperar a que viewDidAppear/viewDidDisappear saber la transición actual ha completado' * primer tiro pila de llamadas: (0x394932a3 0x31db297f 0x3949315d 0x383fd2af 0x3640377b 0x36402fcf 0x394969c4 0x393edfeb 0x36521733 0x32a83d2d 0x3264b11f 0x3264a4b7 0x3264f1bd 0x39466f3b 0x393d9ebd 0x393d9d49 0x353132eb 0x3636b301 0x7e863 0x7e808) libC++ ABI .dylib: Terminar llamada lanzar una excepción

Este es el código problemático:

-(void)authenticateLocalUser { 

    if (!self.checkingLocalPlayer) { 
     self.checkingLocalPlayer = YES; 
     GKLocalPlayer *thisPlayer = [GKLocalPlayer localPlayer]; 

     if (!thisPlayer.authenticated) { 

      [[GKLocalPlayer localPlayer] 
      authenticateWithCompletionHandler:^(NSError *error) 
      { 
       [self finishGameCenterAuthWithError:error]; 
      } 
      ]; 
     } 
    } 
} 

un ¿Idea lo que estoy haciendo mal aquí?

Respuesta

7

Ggrrrhhh mismo problema, creo que lo encontré ... ios6 se ha desaprobado authenticateWithCompletionHandler ver enlace, el que propone utilizar AuthenticateHandler.

http://developer.apple.com/library/IOS/#documentation/GameKit/Reference/GKLocalPlayer_Ref/Reference/Reference.html#//apple_ref/occ/instp/GKLocalPlayer/authenticateHandler

Esto parece funcionar ...

GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer]; 
[localPlayer setAuthenticateHandler:(^(UIViewController* viewcontroller, NSError *error) { 

//[localPlayer authenticateWithCompletionHandler:^(NSError *error) { OLD CODE! 
    if (localPlayer.isAuthenticated) 
    { 
     //do some stuff 
    } 
    else { 

     UIAlertView *alertView = [[UIAlertView alloc] 
            initWithTitle:@"NOT AUTHORISED" 
            message:@"YOUR'RE NOT LOGGED INTO GC." 
            delegate:self 
            cancelButtonTitle:@"OK" 
            otherButtonTitles:nil]; 
     [alertView show]; 

    } 
})]; 
+0

Este fue de hecho el problema. Tengo algunos comentarios adicionales cerca como otra respuesta. –

+0

Sí, gracias por la construcción en el ios 6 vs otro. También creo que presentModalViewController también está en la lista de cortes para ios 6. –

3

Jamie West señaló correctamente que el problema era el paso a authenticateHandler en iOS 6, que parece haber dejado authenticateWithCompletionHandler: roto. Dado que ha sido desaprobado, es poco probable que Apple solucione su error.

Aquí está todo lo que necesitaba.Tenga en cuenta tanto el condicional para verificar la versión de iOS5 (para admitir tanto 5 como 6) y la necesidad de llamar un controlador de vista si se envía (por ejemplo, authenticateHandler: no es un reemplazo directo de authenticateWithCompletionHandler: debe hacer un trabajo adicional)

-(void)authenticateLocalUser { 

    if (!self.checkingLocalPlayer) { 
     self.checkingLocalPlayer = YES; 
     GKLocalPlayer *thisPlayer = [GKLocalPlayer localPlayer]; 

     if (!thisPlayer.authenticated) { 

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) 

      if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) { 

       [thisPlayer setAuthenticateHandler:(^(UIViewController* viewcontroller, NSError *error) { 

        if (viewcontroller) { 
         [self.delegate presentViewController:viewcontroller]; 
        } else { 
         [self finishGameCenterAuthWithError:error]; 
        } 

       })]; 

      } else { 

       [[GKLocalPlayer localPlayer] 
       authenticateWithCompletionHandler:^(NSError *error) 
       { 
        [self finishGameCenterAuthWithError:error]; 
       } 
       ]; 
      } 

     } 
    } 
} 

El presentViewController: función de llamadas con sólo hasta el nuevo controlador de vista de mi top controlador de vista (que tuve que averiguar a mano en mi programa para hacer todo este trabajo):

-(void)presentViewController:(UIViewController *)thisVC { 

    [myTopVC presentModalViewController:thisVC animated:YES]; 

} 

Desafortunadamente , a partir de iOS6, parece que GameCenter no intentará volver a autenticar a un usuario si ya se ha cancelado en la sesión actual, por lo que al menos parte de mi punto de reautorización, cuando corresponda, ya no existe. Pero, todavía está allí para iOS5 (y tal vez otras situaciones que cancelar?).

intentará reescribir cuando la aplicación se recupera desde el modo reposo si un usuario se ha ido y ha hecho otra cosa.

+0

¿Alguna razón por la que está revisando la versión de iOS en lugar de simplemente verificar si el método 'setAuthenticateHandler:' está disponible? Me pregunto si esto podría no estar documentado en iOS <6 ... – megastep

+0

Me pareció más claro. –

+1

Bueno, a menos que sea absolutamente necesario, Apple recomienda encarecidamente verificar la disponibilidad de selectores y clases en lugar de buscar versiones específicas de iOS. Siempre puede agregar un comentario en su código si desea que se le recuerde el motivo ... – megastep

1

Tuve exactamente el mismo problema y el mensaje de bloqueo similar y las respuestas anteriores no resolvieron el problema.

2012-09-25 15:55:25.569 APP NAME [1493:907] * Terminating app due to uncaught exception 
'NSInternalInconsistencyException', reason: 'Attempting to begin a modal transition from 
<GKModalRootViewController: 0x1cd8b2a0> to <GKHostedAuthenticateViewController: 0x1e31a350> 
while a transition is already in progress. Wait for viewDidAppear/viewDidDisappear to know 
the current transition has completed' 

Lo que realmente causó el problema para mí fue que me llamaron - (void) authenticateLocalPlayer entre - (void) viewDidLoad. Una vez que moví la llamada a - (void) viewDidAppear, se corrigió todo, incluso con la forma obsoleta de llamar. (reference to this question)

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 

    //Setup Game Center Manager 
    if ([GameCenterManager isGameCenterAvailable]) { 
     delegate.gameCenterManager = [[GameCenterManager alloc] init]; 
     [delegate.gameCenterManager setDelegate:delegate]; 
     [delegate.gameCenterManager authenticateLocalUser]; 
    } else { 
     // The current device does not support Game Center. 
    } 

    //... more things if you have 
} 
+0

publique su código marcwjj –

+0

Código publicado según lo solicitado. – marcwjj

Cuestiones relacionadas