1

Is a valid, even in case of an authentication error?

GKLocalPlayer.localPlayer.authenticateHandler =
  ^(UIViewController *viewController, NSError *error)
{
  if (error)
  {
    bool a = GKLocalPlayer.localPlayer.authenticated;
  }
  else
  {

This happens for instance when I have an authenticated player, moves the app to the background, disables the WiFi, and then move the app to foreground again. My hope is that GameCenter just continues with a cached account?

I find the manual a bit ambiguous. From https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/GameKit_Guide/Users/Users.html#//apple_ref/doc/uid/TP40008304-CH8-SW11:

"As soon as your game moves to the background, the value of the local player object’s authenticated property becomes and remains invalid until your game moves back to the foreground. You cannot read the value to determine if the player is still authenticated until Game Kit reauthenticates the player and calls your authentication handler. Your game must act as though there is not an authenticated player until your completion handler is called. Once your handler is called, value stored in the authenticated property is valid again."

Is the value valid even though the authentication failed?

Fredrik Johansson
  • 1,301
  • 1
  • 13
  • 26

1 Answers1

1

I have a long-running Bug with Apple on this. It's been closed and re-opened during the ongoing dialog. The question of whether or not .authenticated is valid seems to depend on your perspective

Apple views this as working-as-intended as you have cached information which Apple believes lets you go ahead and play your game, you can display leaderboards, etc. Apple says that .authenticated is indeed valid in this state. I've seen some developers on this forum agree with that perspective, although I don't have links handy to their posts.

In practice, though, if you attempt to do any subsequent game center operation while in this state, it will fail because you're not really authenticated. You can't save games, load matches, etc. Any leaderboard you display will be stale, cached data.

It appears to me that Apple loathes for players to ever see a problem resulting from their infrastructure. Thus, with this mechanism you attempt to drive forward by faking the state, hoping the problem works itself out later. In my games, that strategy never pans out and eventually reaches an unrecoverable situation after users have invested time/effort into the game. So, like your code above, I rely on what the NSError says. If is says "error" then I treat the player as unathenticated, providing UI prompts to correct the situation.

I've documented more details on my approach here: https://stackoverflow.com/a/37216566/1641444

Community
  • 1
  • 1
Thunk
  • 4,099
  • 7
  • 28
  • 47
  • In a mobile environment you can't guarantee connectivity, so maybe apples approach is the way to go? The authenticated attribute states the authentication state, and does so by using cached info if needed. It does not guarantee that the next network operation will be successful. How could it? – Fredrik Johansson Aug 01 '16 at 06:54
  • Fair point. My gripe is when it already knows it can't connect, like in Airplane mode, yet still reports authenticated. Or reporting cached results *without* telling me. I suggested in my bug to make it a 3-state value: authenticated, unauthenticated, and cached. Then I'll fully understand the state I'm in and can choose how to proceed. It's probably a moot point. I seriously doubt they're going to change anything. – Thunk Aug 02 '16 at 04:35