2012-10-13 5 views
26

Wenn das authenticateHandler in iOS 6 verwendet wird, zeigt das Game Center die Anmeldeansicht nicht an, wenn der Benutzer es abbricht. Ich weiß, dass Game Center eine App nach 3 Cancel-Versuchen automatisch aussperrt, aber ich spreche von nur 2 Versuchen. Wenn sie den Login abbrechen, müssen sie die App verlassen und kommen zurück, bevor das Game Center den Login präsentiert, auch wenn der AuthenticateHandler wieder gesetzt wird. Irgendwelche Ideen, wie man mit diesem Fall in iOS 6 umgehen kann?iOS 6 Game Center authenticateHandler kann sich nach einem Abbruch nicht anmelden

Es funktioniert gut, wenn die ältere authenticateWithCompletionHandler Methode:

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

Der Grund für meine App wichtig ist, ist, dass es Game Center für Multi-Player erfordert. Die App versucht sich beim Start am Game Center zu authentifizieren, aber wenn der Benutzer abbricht, fragen wir sie beim Start nicht mehr, damit sie nicht gequält werden. Was wir tun, zeigt eine Game Center Login-Schaltfläche, wenn sie nicht eingeloggt sind, wenn sie Multiplayer auswählen. Der Login-Button erzwingt einen Login des Game Centers durch den Aufruf von authenticateWithCompletionHandler (und jetzt durch erneutes Setzen von GKLocalPlayer.localPlayer.authenticateHandler).

+1

Es klingt, als würden Sie dies bereits tun, aber das Aufrufen von [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler: nil] führt dazu, dass der authenticateHandler erneut mit einem Authentifizierungs-View-Controller aufgerufen wird. Diese Methode ist in iOS6 jedoch veraltet. – Greg

+0

Ich benutze den abgeschriebenen Anruf, um dies zum Laufen zu bringen, aber ich suche nach dem "richtigen" Weg, dies zu tun, ohne veraltete Aufrufe zu verwenden. Ich habe versucht, den neuen GKLocalPlayer.localPlayer.authenticateHandler auf null und dann zurück zu meinem Handler zu setzen, um zu sehen, ob das funktionieren würde, und habe eine Ausnahme bekommen, die versucht, es auf Null zu setzen.Ich habe nicht versucht, es zu einem anderen Handler zu setzen, um zu sehen, ob das ein Login auslösen würde (das schien wirklich wirklich hacky) –

+0

Ich habe versucht, den Handler zu einem anderen Handler zu schalten, und das löst auch keine neue Login-Dialogöffnung aus . Ich habe in den Entwicklerforen gepostet, um zu sehen, ob jemand einen Ratschlag hat, und werde hier zurück posten, wenn ich etwas höre. https://devforums.apple.com/message/744983 – Greg

Antwort

2

Bessere Laufzeitprüfungen (instancesRespondToSelector :) anstelle von Präprozessor-Anweisungen #if verwenden, damit Sie die empfohlenen Methoden verwenden können, wo sie verfügbar und an anderer Stelle abgeschrieben sind. Ich fand ich drei Fälle unterschieden werden müssen, bevor der Handler laden zu stellen, da die Authentifizierung Handler auch mit einem Null-View-Controller aufgerufen könnte:

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

Noch mehr Fälle zu unterscheiden muss innerhalb der Handler laden, wie matchForInvite: : ist auch in iOS6 neu und vermeidet noch eine weitere Runde durch Controller Ansicht Spiel Zentrum:

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

Lassen Sie mich wissen, ob das hilft.

+1

Die Preprozessor-Makros waren nur zum Debuggen und Anzeigen des Problems. Das Problem, das ich habe, ist, dass Sie keine Anmeldung mit der öffentlichen API von iOS 6 auslösen können, wenn der Benutzer die anfängliche Anmeldung, die von Game Center angezeigt wird, abbricht. Die pre-ios6-API unterstützt dieses Verhalten durch Zurücksetzen des Handlers. –

0

Ich glaube nicht, dass dies in iOS 6.0 möglich ist. In den frühen SDK-Builds, die vor der Veröffentlichung entfernt wurden, gab es dazu API-Aufrufe.

In der WWDC 2012 Video: Session 516 - Ihre Spiele mit Game Center Integration [08.30] Sie zeigen tatsächlich Code, in dem Sie eine authenticate Methode aufrufen:

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

Diese Methode ist jetzt private API, aber sie sehen sie in Aktion kann durch den Aufruf:

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

es tut genau das, was Sie wollen, aber kann nicht verwendet werden, weil es jetzt privat ist.


Sie können auch den Authentifizierungsprozess auslösen, indem die UIApplicationWillEnterForegroundNotification Benachrichtigung erfolgt:

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

Ich nehme an, es nicht ratsam wäre, diese in Live-Code zu tun.