如何在AppDelegate的GIDSignIn回调中实例化视图控制器实现登录跳首页
问题排查及解决方案
核心原因及修复点
- UI操作未在主线程执行:GIDSignIn的登录回调默认在后台队列触发,所有UI层修改必须放在主队列执行,否则会出现操作不生效的问题。
- iOS 13+ 窗口管理适配问题:iOS 13及以上版本新建项目默认启用SceneDelegate管理窗口生命周期,此时AppDelegate的
window属性为nil,直接修改self.window?.rootViewController不会生效。 - 配置校验:需要确认Storyboard中TabBarController的
Storyboard ID和Constants.Storyboard.tabBarController取值完全一致,且已勾选「Use Storyboard ID」选项。
完整修复代码
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) { // 先判断登录是否出错 if let error = error { print("Google登录失败: \(error.localizedDescription)") return } print("User Email: \(user.profile.email ?? "No Email")") // UI操作必须放到主队列执行 DispatchQueue.main.async { let mainStoryboard = UIStoryboard(name: "Main", bundle: nil) let homePage = mainStoryboard.instantiateViewController(identifier: Constants.Storyboard.tabBarController) // 适配不同版本窗口获取逻辑 if #available(iOS 13.0, *) { guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, let sceneDelegate = windowScene.delegate as? SceneDelegate, let window = sceneDelegate.window else { return } window.rootViewController = homePage window.makeKeyAndVisible() } else { guard let window = UIApplication.shared.delegate?.window as? UIWindow else { return } window.rootViewController = homePage window.makeKeyAndVisible() } } }
可选简化方案
如果你的项目不需要支持多场景,可以直接在Info.plist中删除Application Scene Manifest配置项,此时AppDelegate的window属性会正常生效,仅需将原有UI操作包裹在DispatchQueue.main.async中即可。
内容的提问来源于stack exchange,提问作者amirbt17
相关产品推荐
相关产品推荐

