Game Center authentication workflow

Prior to iOS 14.5, I adopted the following workflow for my Game Center enabled game - At the launch, if there is no authenticated GKLocalPlayer, then store the viewController passed in the completion handler and display it later to the user (i.e. not immediately after the app completes launching).

I am using the following code for the authentication process -

        GKLocalPlayer.local.authenticateHandler = {viewController, error in

            if (viewController != nil){

            //store the viewController and present it at a later time

            } else if (GKLocalPlayer.local.isAuthenticated) {

           //successfully authenticated

            } else {

           // player could not be authenticated

            }

Since iOS 14.5 the callback to the authenticationHandler seems to have changed. The login prompt is displayed automatically after app launch, if there is no authenticated player. I checked - the completionHandler is not even being called in this case before the login prompt is presented. If there is already an authenticated player on the device, then the handler is called as expected.

How can I prevent the login prompt from being displayed automatically by the system? Is there a new workflow for authenticating a player from iOS 14.5 onwards?

thanks,

Same problem. It doesn't seem like the authentication handler is being called. I get an error that I'm trying to present a view controller when there's already one being presented, which I assume is the login view controller, but I don't seem to have any way to get the login view controller on my own before the error happens.

Check if Game Center is enabled in the settings of the device. It wasn't, for me, and when I turned it on it worked. It seems like the setting got reset when the simulator was upgraded to the latest OS.

Same problem.

It seems like Apple used to trust us to show the login view controller in the course of authentication, but now it just forces the login controller on us on its own.

This is causing me crashes, because Apple tries to make my root controller present the login controller, even though my root controller is already presenting a different controller.

So it's forcing a view controller on me, without warning, and then blaming me for not being able to present it.

Not cool!

Same problem here. The official documentation doesnt reflect this behaviour.

I'm having the same issue, and it seems like others in this thread are, too

Same problem here. Has anyone found any workarounds to this issue?

I've found half of a solution but I can't figure out the other half.

  • I use a custom ViewController as my root VC, and it has a "stashedViewController" property.
  • I override the present(etc) function, and inside it I check if a ViewController is already being presented.
  • If there's already a presentedViewController, I put the interloping ViewController into the stashedViewController property and I return without presenting it

...so this is half a solution because it is indeed keeping my app from crashing...

...but the other half is that I have to figure out what to do with this stashed controller.

It's not hard to figure out how to hand it over to the current top-level ViewController for presenting, what's hard is figuring out for sure whether or not the stashed controller is indeed a Game Center login ViewController.

I can tell during debugging that the class is actually GKHostedAuthenticateViewController, but apparently we're not supposed to be able to explicitly check for that class, so I'm a bit at a loss how to proceed.

Any ideas?

FYI, I brought this up to a few members of the Game Center team at WWDC '23. It seemed as though it was the first they'd heard of it and said they would investigate (yay!). TBD 😅

Game Center authentication workflow
 
 
Q