2014-08-29 41 views
3

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

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

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

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

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

我在游戏中心的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不工作。任何人都可以帮忙吗?

回答

7

假设您已经在您的应用中启用了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) 
    }  
} 

您已经成功验证,那么之后你应该能够呈现游戏中心。

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

要获得工作,你需要做一些黑客获得GKLocalPlayer在斯威夫特正确实例。

创建Objective-C中一个新的类,并命名该文件GKLocalPlayerHack.h /平方米

在头放:

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

+0

这看起来不错,虽然我在使用'scene'变量的行上出错,因为它没有被声明。我该怎么做呢? – user2397282 2014-08-31 16:01:41

+0

编辑答案以包含场景变种。 – 2014-08-31 16:33:00

+0

好的,应用程序在尝试执行这4行时似乎不断崩溃。我评论他们,并且我收到一些错误,表示它无法进行身份验证,但我的分数已添加到Game Center中,我可以查看它。为什么是这样? – user2397282 2014-08-31 17:36:52

0

我以这种方式解决了这个问题测试模式:

进入游戏中心应用标签“朋友”点击屏幕的末尾设置: SANDBOX和记录必须在MODE

我希望它的作品给大家

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)在您的斯威夫特桥接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) 
    } 
} 

}