How to Fix My App Crashing When Game Center Is Logged Out

A while back, I ran into a super frustrating bug with my iOS game. Every time I launched the app and Game Center was logged out, it crashed immediately. Oddly enough, when Game Center was logged in, the app worked perfectly fine.

If you’ve ever been in the same boat, you know how baffling it feels. After some digging, testing, and head scratching, I found out what was wrong and how to fix it properly. So I’m sharing my process here in case it helps you avoid the same headache.

The Original Code

Here’s the snippet I was originally using to authenticate Game Center:

[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error) {
if (error == nil) {
// Insert code here to handle a successful authentication.
//gcSuccess = YES;
}
else
{
// Your application can process the error parameter to report the error to the player.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Could not connect with Game Center servers." delegate:nil cancelButtonTitle:@"Try Later" otherButtonTitles:nil];
[alert show];
}
}];

It seemed straightforward: try to authenticate, show an error if it fails. But when Game Center was logged out, this code led to a crash. The only error message I got was a vague system log about BKSendGSEvent ERROR not helpful.

What Was Actually Wrong

After analyzing everything, I identified a few root issues:

Key Problems:

  1. authenticateWithCompletionHandler: is deprecated since iOS 6.0. I had missed this in the documentation.
  2. I wasn’t checking if the user was authenticated before using Game Center features (like fetching scores or achievements).
  3. UIAlertView is deprecated since iOS 9.0, and shouldn’t be used at all.
  4. Most importantly: I wasn’t handling the authentication view controller that Apple expects to present when Game Center needs user interaction (like login).

The Correct Code

I rewrote the logic using the current recommended authenticateHandler method. Here’s the improved code:

GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];

localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
if (viewController != nil) {
// If Game Center needs to present a login UI
UIViewController *rootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
[rootVC presentViewController:viewController animated:YES completion:nil];
} else if (localPlayer.isAuthenticated) {
NSLog(@"Game Center Authentication Successful!");
// Proceed with Game Center features (e.g., load achievements, scores)
} else {
NSLog(@"Game Center Authentication Failed: %@", error.localizedDescription);

// Show error using UIAlertController
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Game Center Error"
message:@"Unable to connect to Game Center. Please try again later."
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:okAction];

UIViewController *rootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
[rootVC presentViewController:alert animated:YES completion:nil];
}
};

Now, this code covers all three cases:

  1. Game Center needs to log in → it shows the login view.
  2. Game Center is already logged in → I move ahead.
  3. Game Center fails → show a proper alert.

Extra Functionalities I Added

Once the crashing was fixed, I added a few helpful features for better UX and stability.

Check Login Status and Update UI

- (void)checkGameCenterStatus {
GKLocalPlayer *player = [GKLocalPlayer localPlayer];
if (player.isAuthenticated) {
self.gcStatusLabel.text = @"Game Center: Connected";
self.leaderboardButton.enabled = YES;
} else {
self.gcStatusLabel.text = @"Game Center: Not Connected";
self.leaderboardButton.enabled = NO;
}
}

This method lets the user know whether they’re connected, and disables buttons that shouldn’t be used when not authenticated.

Optionally Check for Internet

Game Center login also requires internet. You could add an internet check before calling authenticateHandler, especially if your game needs it for online modes or leaderboards.

You could use Reachability or a third party library like Reachability.swift for this.

Final Thought

Fixing this crash taught me two important lessons:

  • Always use the latest API patterns especially for system services like Game Center.
  • Check all edge cases: users might not be logged in, and apps must handle that gracefully.

If your app is crashing due to Game Center, chances are you’re using outdated methods or missing a required step in the auth flow. Update to authenticateHandler, and make sure you always present the login view controller when it’s provided.

Related blog posts