GameKit自动弹出认证视图控制器而非等待主动呈现问题咨询
问题原因
该自动弹出UI的行为是iOS 16及更高版本的系统默认逻辑,并非你的代码实现错误,对应官方文档确实未及时更新说明。
苹果从iOS 16开始调整了Game Center的认证机制,只要代码中设置了GKLocalPlayer.local.authenticateHandler,系统就会自动判断当前登录状态,需要认证时会直接弹出官方登录UI,此时认证闭包返回的viewController参数会固定为nil,不需要开发者主动持有、呈现。
针对你的两个需求的解决方案
- 若不想在App启动时立刻弹出登录UI,把
authenticateHandler的设置时机从页面onAppear阶段,推迟到用户点击「Play Online」等需要使用Game Center功能的节点即可,无需在App启动/页面加载时就提前设置。 - 用户首次拒绝登录后,后续需要唤起登录的场景,不需要再获取视图控制器,直接重新给
GKLocalPlayer.local.authenticateHandler赋值一次即可,系统会自动判断当前登录状态,用户未登录就会再次弹出Game Center登录UI。
适配后的代码示例
struct ActiveGamesView: View { @State private var gameCenterEnabled = false @State private var isMultiplayerGamingRestricted = true @State private var isPersonalizedCommunicationRestricted = true var body: some View { NavigationView { VStack { Spacer() NavigationLink(destination: Text("This is the online play area")) { Text("Play Online") } .simultaneousGesture(TapGesture().onEnded { authenticateGameCenter() }) } } } private func authenticateGameCenter() { // 每次需要校验登录状态时重新设置handler即可,系统会自动处理UI弹出 GKLocalPlayer.local.authenticateHandler = { _, error in gameCenterEnabled = error == nil isMultiplayerGamingRestricted = GKLocalPlayer.local.isMultiplayerGamingRestricted isPersonalizedCommunicationRestricted = GKLocalPlayer.local.isPersonalizedCommunicationRestricted if !gameCenterEnabled { // 可在此处弹出提示,引导用户去系统设置开启Game Center,或做降级处理 } } } }
旧系统兼容说明
如果你的App需要支持iOS 15及更低版本,可以添加系统版本判断做兼容:
- iOS 15及以下:按照原文档逻辑,保存闭包返回的
viewController,需要时主动呈现 - iOS 16及以上:直接忽略
viewController参数,由系统自动处理UI弹出
内容的提问来源于stack exchange,提问作者Hash88
相关产品推荐
相关产品推荐

