Swift - 游戏中心不可用

Posted

技术标签:

【中文标题】Swift - 游戏中心不可用【英文标题】:Swift - Game Center not available 【发布时间】:2014-08-29 13:12:43 【问题描述】:

我正在尝试在我的 Swift 游戏中实现 Game Center。我有一个菜单视图控制器,用户可以在其中按下“分数”按钮,这会将他们带到 Game Center 视图控制器。

这是在菜单 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

我不知道这意味着什么,也不知道 Game Center 为何不工作。有人可以帮忙吗??

【问题讨论】:

【参考方案1】:

假设您在应用中启用了 Game Center,并且还在 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)
        

在您成功通过身份验证后,您应该可以展示 Game Center。

注意这一行: var localPlayer = getLocalPlayer() // see GKLocalPlayerHack.h

要让它工作,你需要做一些小技巧来让 GKLocalPlayer 在 Swift 中正确实例化。

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

在标题中放置:

//  GKLocalPlayerHack.h
// Issue with GameKit and Swift
// https://***.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://***.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

【讨论】:

这看起来不错,尽管我在使用 scene 变量的行上遇到错误,因为它尚未被声明。我该怎么做? 编辑了答案以包含场景变量。 好的,应用程序在尝试执行这 4 行时似乎一直在崩溃。我将它们注释掉,我收到一些错误,说它无法验证,但我的分数已添加到游戏中心,我可以查看它。这是为什么呢? 您正在运行 Xcode beta 6 吗?在早期的 GC 和 Swift 测试版中,存在一个已知的身份验证问题。 那么您能否再次澄清一下您的应用程序现在发生了什么?您是否收到 GC 提示登录? GC 视图控制器是否显示?你说查看分数是指你可以在GC中看到分数吗?【参考方案2】:

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

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

希望对大家有用

【讨论】:

【参考方案3】:

你可以使用它,我在 github 上为 ios 游戏中心创建了一个 Easy Game Center 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 "GKLocalPlayerHack.h"

下一步

class GameCenter 

// Game Center

let gameCenterPlayer=GKLocalPlayer.localPlayer()
var canUseGameCenter:Bool = false 
    didSetif 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)
    

【讨论】:

以上是关于Swift - 游戏中心不可用的主要内容,如果未能解决你的问题,请参考以下文章

Swift - 坐标不可用:从 iOS 7 开始不推荐使用 API

Swift 参数标签 '(_:, destination:)' 不匹配任何可用的重载

Swift 3.0:参数标签 '(_:) 不匹配任何可用的重载

Swift如何检查API是不是不可用[重复]

Swift URL resourceSpecifier 不可用

在随机颜色数组中替换属性 CGColorGetComponents(在 swift 4 中不可用)