iosobjective-cswiftgame-centergame-center-leaderboard

Present GameCenter authenticationVC again


I'm facing a little issue here and I hope someone will help me figure out what is wrong.

I'm trying to present to the user the authentification view controller proposed by apple for the GameCenter feature. More precisely, re-present it if he canceled it on the first time.

I have a game with a storyboard like that :

Storyboard

GameNavigationController :

class GameNavigationController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("showAuthenticationViewController"), name: PresentAuthenticationViewController, object: nil)
        
        GameKitHelper.sharedInstance.authenticateLocalPlayer()
    }
    
    func showAuthenticationViewController() {
        let gameKitHelper = GameKitHelper.sharedInstance
        
        if let authenticationViewController = gameKitHelper.authenticationViewController {
            self.topViewController.presentViewController(authenticationViewController, animated: true, completion: nil)
        }
    }
    
    deinit {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
}

MenuViewController :

class MenuViewController: UIViewController {
    @IBAction func didTapLeaderboardBTN() {
        // TRY 2
        //if ( !GameKitHelper.sharedInstance.gameCenterEnabled) {
            GameKitHelper.sharedInstance.authenticateLocalPlayer()
        //} else {
            GameKitHelper.sharedInstance.showGKGameCenterViewController(self)
        //}
    }
}

GameKitHelper :

import GameKit
import Foundation

let PresentAuthenticationViewController = "PresentAuthenticationViewController"

let singleton = GameKitHelper()

class GameKitHelper: NSObject, GKGameCenterControllerDelegate {
    
    var authenticationViewController: UIViewController?
    var lastError: NSError?
    var gameCenterEnabled: Bool
    
    class var sharedInstance: GameKitHelper {
        return singleton
    }
    
    override init() {
        gameCenterEnabled = true
        super.init()
    }
    
    func authenticateLocalPlayer () {
        
        let localPlayer = GKLocalPlayer.localPlayer()
        localPlayer.authenticateHandler = { (viewController, error) in
            
            self.lastError = error
            
            if viewController != nil {
                self.authenticationViewController = viewController
                NSNotificationCenter.defaultCenter().postNotificationName(PresentAuthenticationViewController, object: self)
            } else if localPlayer.authenticated {
                self.gameCenterEnabled = true
            } else {
                self.gameCenterEnabled = false
            }
        }
    }
    
    func showGKGameCenterViewController(viewController: UIViewController!) {
        
        if ( !self.gameCenterEnabled ) {
            println("Local player is not authenticated")
            
            // TRY 1
            //self.authenticateLocalPlayer()
            
            return
        }
        
        let gameCenterViewController = GKGameCenterViewController()
        
        gameCenterViewController.gameCenterDelegate = self
        
        gameCenterViewController.viewState = .Leaderboards
        
        viewController.presentViewController(gameCenterViewController, animated: true, completion: nil)
    }

    func gameCenterViewControllerDidFinish(gameCenterViewController: GKGameCenterViewController!) {
        gameCenterViewController.dismissViewControllerAnimated(true, completion: nil)
    }
}

What is currently working :

What is NOT currently working :

I tried 2-3 things as you can see in the commented code above, but none of them is working ; I can't make the authentification view appear again.

PS : My code is written in Swift, but help in Objective-C is welcomed as well.


Solution

  • As you have found out, if the Game Center authentication dialog is canceled 3 times, then you can't bring it back without resetting the device.

    There is another "security feature" built into Game Center which does not allow an app to re-authenticate if the user has already canceled the dialog without leaving the app. So for your authentication dialog to show, the user must leave and then re-enter your app.

    There is really no way around it. What I've done in a couple of projects is to display a message to the user:

    Game Center not available. Please make sure you are signed in through the Game Center app

    I will show that message after trying to authenticate and if Game Center isn't available or the user is not signed in.