GameCenter 分数未发布到排行榜

GameCenter scores are not being posted to the leaderboard

请耐心等待,因为有很多内容需要解释!

我正在努力在我的游戏中实现 Game Center 高分排行榜。我四处寻找有关如何正确实施此代码的示例,但没有找到很多 material。因此,我尝试根据我在苹果文档中找到的信息自己实现它。

长话短说,当我更新我的分数时,我得到了成功打印,但实际上没有分数被 posted(或者至少打开时游戏中心排行榜上没有显示分数) .

在我展示代码之前,我质疑的一件事是这款游戏仍在开发中。在 AppStoreConnect 中,排行榜的状态为“未上线”。这会影响 posted 的分数吗?

进入代码。我创建了一个 GameCenter class 来处理获取排行榜和 post 将分数添加到特定排行榜。我将 post 整个代码,并将在下面讨论发生了什么。

class Leaderboard
{
   var id          : String
   var leaderboard : GKLeaderboard
   var loaded      : Bool

   init()
   {
       self.id          = ""
       self.leaderboard = GKLeaderboard()
       self.loaded      = false
   }
 
   init(id: String, leaderboard: GKLeaderboard, loaded: Bool)
   {
       self.id          = id
       self.leaderboard = leaderboard
      self.loaded      = loaded
   }
}

class GameCenter
{
   static let shared = GameCenter()

   private var player = GKLocalPlayer.local
   private var leaderboards : [Leaderboard] = []

   func authenticatePlayer()
   {
      player.authenticateHandler = { (vc, error) -> Void in
         if let error = error
         {
            print(error.localizedDescription)
         }
         else if let vc = vc
         {
            if let viewController = UIApplication.shared.windows.first!.rootViewController
            {
               viewController.present(vc, animated: true)
               {
                  self.loadLeaderboards()
               }
            }
         }
         else
         {
            self.loadLeaderboards()
         }
      }
   }

   func loadLeaderboards()
   {
      var leaderboardIDs : [String] = []
    
      // Gather all of the leaderboard ids that we have
      for leaderboard in GameCenterLeaderboards.allCases
      {
         leaderboardIDs.append(leaderboard.rawValue)
      }
    
      // Load the leaderboard for all of these ids and add to a new array
      GKLeaderboard.loadLeaderboards(IDs: leaderboardIDs) { (loadedLeaderboards, error) in
        
         if let error = error
         {
            print(error.localizedDescription)
            return
         }
        
         if let loadedLeaderboards = loadedLeaderboards
         {
            print("\n--- Loaded Leaderboards ---")
            for loadedBoard in loadedLeaderboards
            {
               let board = Leaderboard(id: loadedBoard.baseLeaderboardID, leaderboard: loadedBoard, loaded: true)
               self.leaderboards.append(board)
                
               print("ID: \(board.id)")
            }
            print("\n")
            
            self.updateLocalHighScore()
         }
      }
   }

   func playerAuthenticated() -> Bool
   {
      return player.isAuthenticated
   }

   func submitScore(id: String)
   {
      if ( playerAuthenticated() )
      {
         let leaderboard = getLeaderboard(id: id)
         if ( leaderboard.loaded )
         {
            print("Submitting score of \(AppSettings.shared.highScore!) for leaderboard \(leaderboard.id)")
            leaderboard.leaderboard.submitScore(AppSettings.shared.highScore, context: -1, player: player) { (error) in
               if let error = error
               {
                  print(error.localizedDescription)
               }
               else
               {
                  print("Successfully submitted score to leaderboard")
               }
            }
         }
      }
   }

   func getLeaderboard(id: String) -> Leaderboard
   {
      if let leaderboard = leaderboards.first(where: { [=10=].id == id } )
      {
         return leaderboard
      }
    
      return Leaderboard()
   }

   func updateLocalHighScore()
   {
      let leaderboard = getLeaderboard(id: GameCenterLeaderboards.HighScore.rawValue)
      if ( leaderboard.loaded )
      {
         leaderboard.leaderboard.loadEntries(for: [player], timeScope: .allTime) { (playerEntry, otherEntries, error) in
            
            if let error = error
            {
               print(error.localizedDescription)
               return
            }
            
            if let score = playerEntry?.score
            {
               print("Player Score in leaderboard: \(score)")
               if( score > AppSettings.shared.highScore )
               {
                  AppSettings.shared.highScore = score
                  print("High Score Updated!")
               }
               else
               {
                  // Lets post the local high score to game center
                  self.submitScore(id: leaderboard.id)
                  print("Local High Score Is Greating, requesting a submit!")
               }
            }
         }
      }
   }
}

在不同的 GameScene 中,一旦游戏结束,我用这行代码向 Game Center post 请求一个新的高分:

GameCenter.shared.submitScore(id: GameCenterLeaderboards.HighScore.rawValue)

我最后一个问题是提交乐谱时的上下文。根据文档,这似乎只是 GameCenter 不关心的元数据,而是开发人员可以使用的东西。因此,我想我可以把它划掉,因为它是导致问题的原因。

我相信我正确地实现了这一点,但出于某种原因,排行榜上没有任何内容 post。这是很多,但我想确保我把所有的想法都记下来了。

任何关于为什么这不是 posting 的帮助都会很棒!非常感谢!

马克

我遇到了同样的问题 - 使用新的 GameKit API 向 Game Center 提交得分 iOS 14 从未真正保存在 Game Center 端(即使没有任何报告错误)。

最终对我有用的解决方案只是使用 Type Method(带有我的排行榜 ID):

class func submitScore(_ score: Int, 
               context: Int, 
                player: GKPlayer, 
        leaderboardIDs: [String], 
     completionHandler: @escaping (Error?) -> Void)

而不是 Instance Method 对应物(苹果方面显然有一些错误):

func submitScore(_ score: Int, 
         context: Int, 
          player: GKPlayer, 
completionHandler: @escaping (Error?) -> Void)

我为此快疯了,所以我希望这对其他人有帮助。