2012-10-13 14 views
26

Quando si utilizza authenticateHandler in iOS 6, il centro giochi non presenterà la vista di accesso se l'utente lo annulla. Realizzo che Game Center chiuderà automaticamente un'app dopo 3 tentativi di annullamento, ma sto parlando di solo 2 tentativi. Se annullano il login, devono lasciare l'app e tornare prima che il centro giochi possa presentare l'accesso anche attraverso l'autenticazione. Handler viene nuovamente impostato. Qualche idea su come gestire questo caso in iOS 6?iOS 6 Game Center authenticateHandler non può effettuare il login dopo un annullamento

Funziona bene quando si utilizza il metodo più vecchio authenticateWithCompletionHandler:

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

La ragione per questo è importante per la mia app è che richiede Game Center per il multi-player. L'app tenta di autenticare il centro del gioco al momento del lancio, ma se l'utente annulla non glielo chiediamo al momento del lancio, in modo che non vengano tormentati. Quello che facciamo è mostrare un pulsante di accesso al Game Center se non sono registrati quando selezionano il multi-giocatore. Il pulsante di accesso impone l'accesso al centro giochi chiamando authenticateWithCompletionHandler (e ora impostando nuovamente GKLocalPlayer.localPlayer.authenticateHandler).

+1

Sembra che lo stiate già facendo, ma chiamando [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler: nil] farà sì che l'authenticateHandler venga chiamato di nuovo con un controller della vista di autenticazione. Questo metodo è deprecato anche se in iOS6. – Greg

+0

Sto usando la chiamata ammortizzata per farlo funzionare, ma sto cercando il modo "giusto" per farlo senza usare le chiamate deprecate. Ho provato a impostare il nuovo GKLocalPlayer.localPlayer.authenticateHandler su zero e poi di nuovo sul gestore per vedere se funzionasse, e ho ottenuto un'eccezione cercando di impostarlo su zero.Non ho provato a impostarlo su un gestore diverso per vedere se ciò avrebbe attivato un accesso (che sembrava davvero molto hacky) –

+0

Ho provato a passare il gestore a un altro gestore e anche questo non attiva una nuova finestra di accesso . Ho postato sui forum degli sviluppatori per vedere se qualcuno ha qualche consiglio, e posteremo di nuovo qui se sentirò qualcosa. https://devforums.apple.com/message/744983 – Greg

risposta

2

Utilizzare meglio i controlli di runtime (instancesRespondToSelector :) anziché le istruzioni # prep del preprocessore, in modo da poter utilizzare i metodi consigliati laddove sono disponibili e quelli ammortizzati altrove. In realtà ho trovato che ho bisogno di distinguere tre casi prima di impostare il gestore di invito, come il gestore di autenticazione potrebbe anche ottenere chiamato con un nullo controller della vista:

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

Eppure più casi devono essere distinti all'interno del gestore di invitare, come matchForInvite: : è nuovo in iOS6 pure ed evita l'ennesimo giro attraverso gioco controller di vista centro:

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

fatemi sapere se questo aiuta.

+1

Le macro del preprocessore erano solo per il debug e mostravano il problema. Il problema che sto riscontrando è che non è possibile attivare un accesso utilizzando l'API pubblica iOS 6 se l'utente annulla l'accesso iniziale mostrato da Game Center. L'API pre-ios6 supporta questo comportamento ripristinando il gestore. –

0

Non penso che sia possibile in iOS 6.0. Ci sono state chiamate API per fare questo nei primi build dell'SDK che sono stati rimossi prima del rilascio.

nel video WWDC 2012: Sessione 516 - Integrazione tuoi giochi con Game Center [08:30] In realtà mostrano codice in cui si chiama un metodo di authenticate:

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

Questo metodo è ora API private, ma si può vedere in azione chiamando:

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

fa esattamente quello che si vuole, ma non può essere utilizzato perché è ora privato.


Si può anche innescare il processo di autenticazione inviando il UIApplicationWillEnterForegroundNotification notifica:

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

presumo che sarebbe sconsigliabile fare questo nel codice dal vivo.

Problemi correlati