Swift – Game Center not available

I’m trying to implement Game Center in my Swift game. I have a menu view controller, where the user can press a “SCORES” button, which should take them to the Game Center view controller.

This is the code that runs in the menu vc, when the button is pressed:

  • iTunesConnect (Testflight) prerelease testing is over. The app goes to App Store. Can it have the same version number as beta?
  • Dismissing a UIPopoverController from within its contentViewController?
  • Cut rounded image with the face from CIDetector and CIFaceFeature
  • Parse NSURL path and query (iphoneOS)
  • Can multiple NSPersistentStoreCoordinator instances be connected to the same underlying SQLite persistent store?
  • Cocoa Touch - Custom UIButton shape
  • var gcViewController: GKGameCenterViewController = GKGameCenterViewController()
    gcViewController.gameCenterDelegate = self
    
    gcViewController.viewState = GKGameCenterViewControllerState.Leaderboards
    gcViewController.leaderboardIdentifier = "VHS"
    
    self.presentViewController(gcViewController, animated: true, completion: nil)
    

    I have code in the Game Center vc, but I don’t think it gets a chance to run. The app stops execution after this code (no breakpoints or errors, just won’t let me tap anything) and displays a pop up message that reads:

    Game Center Unavailable
    Player is not signed in
    

    The only other response I get is in Xcode, where the following line is printed to the log:

    2014-08-29 14:10:33.157 Valley[2291:304785] 17545849:_UIScreenEdgePanRecognizerEdgeSettings.edgeRegionSize=13.000000
    

    I have no idea what this means or why Game Center is not working. Can anybody help??

    3 Solutions Collect From Internet About “Swift – Game Center not available”

    Assuming that you’ve enabled Game Center in your app and also added a leaderboard in iTunes Connect then you need to authenticate your player before you can show GC. Also, be sure that you’ve created a test user in iTunes Connect that you can use to log in to Game Center when the prompt appears.

    Your MenuViewController should authenticate the local player in viewDidLoad like so:

    class MenuViewController: UIViewController,
                GKGameCenterControllerDelegate
    {
        var leaderboardIdentifier: String? = nil
        var gameCenterEnabled: Bool = false
    
        override func viewDidLoad()
        {
            super.viewDidLoad()
    
            //Your code that sets up your scene or other set up code
    
            //HERE IS WHERE YOU AUTHENTICATE
            authenticateLocalPlayer()
        }
    
        func authenticateLocalPlayer()
        {
            var localPlayer = getLocalPlayer() // see GKLocalPlayerHack.h
            localPlayer.authenticateHandler =
                { (viewController : UIViewController!, error : NSError!) -> Void in
                    if viewController != nil
                    {
                        self.presentViewController(viewController, animated:true, completion: nil)
                    }
                    else
                    {
                        if localPlayer.authenticated
                        {
                            self.gameCenterEnabled = true
                            localPlayer.loadDefaultLeaderboardIdentifierWithCompletionHandler
                            { (leaderboardIdentifier, error) -> Void in
                                if error != nil
                                {
                                    print("error")
                                }
                                else
                                {
                                    self.leaderboardIdentifier = leaderboardIdentifier
                                    print("\(self.leaderboardIdentifier)") //in your example "VHS" should be returned
                                }
                            }
                        }
                        else
                        {
                            print("not able to authenticate fail")
                            self.gameCenterEnabled = false
    
                            if error
                            {
                                print("\(error.description)")
                            }
                            else
                            {
                                print(    "error is nil")
                            }
                        }
                    }
            }
        }
    
    
        func gameCenterViewControllerDidFinish(gameCenterViewController: GKGameCenterViewController!)
        {
            gameCenterViewController.dismissViewControllerAnimated(true, completion: nil)
        }    
    }
    

    After you’ve successfully authenticated then you should be able to present Game Center.

    Note the line:
    var localPlayer = getLocalPlayer() // see GKLocalPlayerHack.h

    To get that to work you need to do a little hack to get GKLocalPlayer to instantiate correctly in Swift.

    Create a new class in Objective-C and name the file GKLocalPlayerHack.h/m

    In the header put:

    //  GKLocalPlayerHack.h
    // Issue with GameKit and Swift
    // https://stackoverflow.com/questions/24045244/game-center-not-authenticating-using-swift
    
    #import <GameKit/GameKit.h>
    
    @interface GKLocalPlayerHack : NSObject
    
    GKLocalPlayer *getLocalPlayer(void);
    
    @end
    

    In the implementation file put:

    // GKLocalPlayerHack.m
    // Issue with GameKit and Swift
    // https://stackoverflow.com/questions/24045244/game-center-not-authenticating-using-swift
    
    #import "GKLocalPlayerHack.h"
    
    @implementation GKLocalPlayerHack
    
    GKLocalPlayer *getLocalPlayer(void)
    {
        return [GKLocalPlayer localPlayer];
    }
    
    @end
    

    Be sure to add:

    #import "GKLocalPlayerHack.h"
    

    To your bridging header.
    Credit to @marmph for his answer in this question: Game Center not authenticating using Swift

    I solved this problem for TEST MODE in this way:

    Go to Game Center App Tab “Friends” click Setting at the end of the screen: SANDBOX and LOGGING MUST BE ON MODE

    I hope that it works for everyone

    You can use that, I create a Easy Game Center for iOS game center in github
    https://github.com/DaRkD0G/Easy-Game-Center-Swift

    Message from France, Merry Christmas

    Begin

    (1) Add FrameWork GameKit.framework

    (2) Create two files :

    GKLocalPlayerHack.h

    #import <GameKit/GameKit.h>
    @interface GKLocalPlayerHack : NSObject
    GKLocalPlayer *getLocalPlayer(void);
    @end
    

    GKLocalPlayerHack.m

    #import "GKLocalPlayerHack.h"
    @implementation GKLocalPlayerHack
    GKLocalPlayer *getLocalPlayer(void) {
        return [GKLocalPlayer localPlayer];
    }
    @end
    

    (3) In your Swift Bridging Header.h (Objectic-c import)

    #import "GKLocalPlayerHack.h"
    

    Next

    class GameCenter {
    
    // Game Center
    
    let gameCenterPlayer=GKLocalPlayer.localPlayer()
    var canUseGameCenter:Bool = false {
        didSet{if canUseGameCenter == true {// load prev. achievments form Game Center
            gameCenterLoadAchievements()}
        }}
    var gameCenterAchievements=[String:GKAchievement]()
    
    /**
        builder
    */
    init(uiControlNow : UIViewController) {
    
    
        // Do any additional setup after loading the view.
        self.gameCenterPlayer.authenticateHandler={(var gameCenterVC:UIViewController!, var gameCenterError:NSError!) -> Void in
    
            if gameCenterVC != nil {
                //showAuthenticationDialogWhenReasonable: is an example method name. Create your own method that displays an authentication view when appropriate for your app.
                //showAuthenticationDialogWhenReasonable(gameCenterVC!)
                uiControlNow.presentViewController(gameCenterVC, animated: true, completion: { () -> Void in
                    // no idea
                })
            }
            else if self.self.gameCenterPlayer.authenticated == true {
                self.self.canUseGameCenter = true
            } else  {
                self.canUseGameCenter = false
            }
    
            if gameCenterError != nil
            { println("Game Center error: \(gameCenterError)")}
        }
    
    
    }
    
    
    /**
        Load prev achievement granted to the player
    */
    func gameCenterLoadAchievements(){
        // load all prev. achievements for GameCenter for the user to progress can be added
        var allAchievements=[GKAchievement]()
    
        GKAchievement.loadAchievementsWithCompletionHandler({ (allAchievements, error:NSError!) -> Void in
            if error != nil{
                println("Game Center: could not load achievements, error: \(error)")
            } else {
                for anAchievement in allAchievements  {
                    if let oneAchievement = anAchievement as? GKAchievement {
                        self.gameCenterAchievements[oneAchievement.identifier]=oneAchievement}
                }
            }
        })
    }
    
    
    /**
        Add progress to an achievement
    
        :param: Progress achievement Double
        :param: ID Achievement
    */
    func gameCenterAddProgressToAnAchievement(progress:Double,achievementID:String) {
        if canUseGameCenter == true { // only update progress if user opt-in to use Game Center
            // lookup if prev progress is logged for this achievement = achievement is already know (and loaded) form Game Center for this user
            var lookupAchievement:GKAchievement? = gameCenterAchievements[achievementID]
    
            if let achievement = lookupAchievement {
                // found the achievement with the given achievementID, check if it already 100% done
                if achievement.percentComplete != 100 {
                    // set new progress
                    achievement.percentComplete = progress
                    if progress == 100.0  {achievement.showsCompletionBanner=true}  // show banner only if achievement is fully granted (progress is 100%)
    
                    // try to report the progress to the Game Center
                    GKAchievement.reportAchievements([achievement], withCompletionHandler:  {(var error:NSError!) -> Void in
                        if error != nil {
                            println("Couldn't save achievement (\(achievementID)) progress to \(progress) %")
                        }
                    })
                }
                else {// achievemnt already granted, nothing to do
                    println("DEBUG: Achievement (\(achievementID)) already granted")}
            } else { // never added  progress for this achievement, create achievement now, recall to add progress
                println("No achievement with ID (\(achievementID)) was found, no progress for this one was recoreded yet. Create achievement now.")
                gameCenterAchievements[achievementID] = GKAchievement(identifier: achievementID)
                // recursive recall this func now that the achievement exist
                gameCenterAddProgressToAnAchievement(progress, achievementID: achievementID)
            }
        }
    }
    /**
        Remove One Achievements
    
        :param: ID Achievement
    */
    func resetAchievements(achievementID:String) {
    
        var lookupAchievement:GKAchievement? = gameCenterAchievements[achievementID]
    
        if let achievement = lookupAchievement {
            GKAchievement.resetAchievementsWithCompletionHandler({ (var error:NSError!) -> Void in
                if error != nil {
                    ToolKit.log("Couldn't Reset achievement (\(achievementID))")
                } else {
                    ToolKit.log("Reset achievement (\(achievementID))")
                }
            })
    
        } else {
            println("No achievement with ID (\(achievementID)) was found, no progress for this one was recoreded yet. Create achievement now.")
    
            gameCenterAchievements[achievementID] = GKAchievement(identifier: achievementID)
            // recursive recall this func now that the achievement exist
            self.resetAchievements(achievementID)
        }
    }
    

    }