Swift - 游戏中心不可用

时间:2014-08-29 13:12:44

标签: ios xcode uiviewcontroller swift game-center

我试图在我的Swift游戏中实现Game Center。我有一个菜单视图控制器,用户可以按下" SCORES"按钮,应该将它们带到游戏中心视图控制器。

当按下按钮时,这是在菜单vc中运行的代码:

var gcViewController: GKGameCenterViewController = GKGameCenterViewController()
gcViewController.gameCenterDelegate = self

gcViewController.viewState = GKGameCenterViewControllerState.Leaderboards
gcViewController.leaderboardIdentifier = "VHS"

self.presentViewController(gcViewController, animated: true, completion: nil)

我在Game Center vc中有代码,但我认为它没有机会运行。应用程序在此代码后停止执行(没有断点或错误,只是赢了让我点击任何内容)并显示一条弹出消息:

Game Center Unavailable
Player is not signed in

我得到的唯一其他响应是在Xcode中,其中以下行打印到日志中:

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

我不知道这意味着什么或游戏中心无法正常工作的原因。有人可以帮忙??

3 个答案:

答案 0 :(得分:7)

假设您已在应用中启用了游戏中心,并在iTunes Connect中添加了排行榜,则需要先验证播放器,然后才能显示GC。此外,请确保您已在iTunes Connect中创建了一个测试用户,可在出现提示时用于登录Game Center。

您的MenuViewController应该在viewDidLoad中对本地播放器进行身份验证,如下所示:

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)
    }    
}

在您成功通过身份验证后,您应该能够展示游戏中心。

请注意以下行: var localPlayer = getLocalPlayer() // see GKLocalPlayerHack.h

为了让它工作,你需要做一点点破解让GKLocalPlayer在Swift中正确实例化。

在Objective-C中创建一个新类,并将文件命名为GKLocalPlayerHack.h / m

在标题中:

//  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

在执行文件中:

// 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

请务必添加:

#import "GKLocalPlayerHack.h"

到您的桥接标题。 感谢@marmph在这个问题中的回答:Game Center not authenticating using Swift

答案 1 :(得分:0)

我用这种方式为TEST MODE解决了这个问题:

转到Game Center应用程序选项卡“朋友”,点击屏幕末尾的设置:SANDBOX和LOGGING必须处于模式

我希望它适用于所有人

答案 2 :(得分:0)

你可以使用它,我在github上为iOS游戏中心创建了一个简易游戏中心 https://github.com/DaRkD0G/Easy-Game-Center-Swift

来自法国的消息,圣诞快乐

开始

(1)添加FrameWork GameKit.framework

(2)创建两个文件:

<强> 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)在你的Swift Bridging Header.h(Objectic-c import)

#import "GKLocalPlayerHack.h"

下一步

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)
    }
}

}