2014-08-29 64 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) 
    } 
} 

}