【问题标题】:Swift - Game Center not availableSwift - 游戏中心不可用
【发布时间】: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 为何不工作。有人可以帮忙吗??

【问题讨论】:

    标签: ios xcode uiviewcontroller swift 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://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

    【讨论】:

    • 这看起来不错,尽管我在使用 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 {
          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)
          }
      }
      

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多