You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:02:26