1

I am working on a new version of my app. I was using the sandbox normally for a while, but now all of my devices are stuck with a very strange problem. They appear to be halfway logged into game center. It doesn't work for them, but they can't log out either. Here is my authentication method:

- (void)authenticateLocalPlayer {
    GKLocalPlayer* localPlayer = WJLocalPlayer;
    WJLog(@"Authenticating local user...");
    if (localPlayer.authenticated == NO) {
        localPlayer.authenticateHandler = ^ (UIViewController* vc, NSError *error) {
            if (error) {
                WJLog(@"Authentication failed! %@", [error localizedDescription]);
            }
            else {
                WJLog(@"Authentication succeeded!");
                NSString* name = [GKLocalPlayer localPlayer].displayName;
                WJLog(@"display name is %@", name);
                NSString* alias = [GKLocalPlayer localPlayer].alias;
                WJLog(@"alias is %@", alias);
                GKTurnBasedEventHandler *ev = [GKTurnBasedEventHandler sharedTurnBasedEventHandler];
                ev.delegate = self;
            }
        };
    }
}

And here is what I am seeing from the log statements [WJLog is just my own version of NSLog without the garbage]:

Authenticating local user...
Authentication succeeded!
display name is Me
alias is (null)

I can log in or out in the game center app. It makes no difference. I always see the above. I even tried restoring one of the devices to factory settings. The result was still the same. I also tried disabling and re-enabling game center for the new version of my app. Still the same result.

Any ideas?

William Jockusch
  • 26,513
  • 49
  • 182
  • 323

1 Answers1

3

You're completely ignoring the UIViewController parameter. You're supposed to present this to the user if it exists, so they can log in. Probably you are only now experiencing this because you logged in to the non-sandbox game center, and now when you run the app it wants to ask you for your sandbox credentials, but instead you're assuming you're authenticated.

You have some other problems here too:

  • You should set the authenticateHandler once only, soon after your app launches.

  • You should check localPlayer.authenticated inside your authenticateHandler, and nowhere else, as this is the only place it's guaranteed to be valid. Specifically, it's a meaningless value after you resume from the background and until your authenticateHandler gets called again. If you need it elsewhere, use a global variable that gets initialised to false at startup and also in your applicationWillEnterForeground method, and only gets set to true inside your authenticateHandler when you've determined that the localPlayer is actually authenticated.

  • Check the error and log it by all means, but it doesn't tell you anything about whether authentication actually succeeded, so remove the 'else'.

Have a look at the documentation here.

sup
  • 806
  • 8
  • 12