GameCenter基础认证代码无法运行或完成认证问题求助
GameCenter 用户认证修复方案
先看你代码里的几个关键问题:
- 认证闭包的参数命名错误,把系统返回的认证视图控制器写成了
AchievementsViewController,导致无法正确获取弹窗控制器 - 尝试present的
vc!完全未定义,这不仅逻辑错误,还会直接引发崩溃 - 闭包内直接用
self存在循环引用风险 - 没有处理用户已认证的分支逻辑
以下是重写后的完整代码,支持在AchievementsViewController加载时触发认证,也可以移到AppDelegate/SceneDelegate实现启动时认证:
import UIKit import GameKit class AchievementsViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() authenticateGameCenterUser() } private func authenticateGameCenterUser() { let localPlayer = GKLocalPlayer.local // 使用weak self避免循环引用 localPlayer.authenticateHandler = { [weak self] viewController, error in guard let self = self else { return } // 处理错误情况 if let error = error { print("GameCenter认证失败: \(error.localizedDescription)") return } // 如果系统返回了认证视图控制器,就弹窗展示 if let authVC = viewController { self.present(authVC, animated: true) } else { // 用户已完成认证,这里可以处理后续逻辑(比如加载成就、排行榜) if localPlayer.isAuthenticated { print("用户已成功登录GameCenter,玩家ID: \(localPlayer.playerID ?? "未知")") // 这里可以调用加载成就/排行榜的方法 } } } } @IBAction func showAchievements(_ sender: Any) { guard GKLocalPlayer.local.isAuthenticated else { print("用户未登录GameCenter,无法查看成就") return } let achievementsVC = GKGameCenterViewController(state: .achievements) achievementsVC.gameCenterDelegate = self present(achievementsVC, animated: true) } @IBAction func showLeaderboards(_ sender: Any) { guard GKLocalPlayer.local.isAuthenticated else { print("用户未登录GameCenter,无法查看排行榜") return } let leaderboardsVC = GKGameCenterViewController(state: .leaderboards) leaderboardsVC.gameCenterDelegate = self present(leaderboardsVC, animated: true) } @IBAction func unlockAchievements(_ sender: Any) { guard GKLocalPlayer.local.isAuthenticated else { print("用户未登录GameCenter,无法解锁成就") return } // 示例:解锁一个成就,替换成你的成就ID let achievement = GKAchievement(identifier: "your_achievement_id") achievement.percentComplete = 100.0 GKAchievement.report([achievement]) { error in if let error = error { print("成就解锁失败: \(error.localizedDescription)") } else { print("成就解锁成功") } } } @IBAction func submit(_ sender: Any) { guard GKLocalPlayer.local.isAuthenticated else { print("用户未登录GameCenter,无法提交分数") return } // 示例:提交分数到排行榜,替换成你的排行榜ID和分数 let score = GKScore(leaderboardIdentifier: "your_leaderboard_id") score.value = 1000 GKScore.report([score]) { error in if let error = error { print("分数提交失败: \(error.localizedDescription)") } else { print("分数提交成功") } } } } // 实现GKGameCenterViewControllerDelegate,关闭页面时dismiss extension AchievementsViewController: GKGameCenterViewControllerDelegate { func gameCenterViewControllerDidFinish(_ gameCenterViewController: GKGameCenterViewController) { gameCenterViewController.dismiss(animated: true) } }
额外需要检查的项目配置:
- 在Xcode中,进入项目的
Signing & Capabilities,添加GameCenter能力 - 确保你的Apple开发者账号已为该Bundle ID开启GameCenter服务
- 模拟器上需要登录Apple ID,并且在
设置 -> GameCenter中启用该账号 - 如果是真机测试,确保设备已登录GameCenter账号
内容的提问来源于stack exchange,提问作者Rebecca
相关产品推荐
相关产品推荐

