取消Google Sign In弹窗后应用无法响应用户交互问题排查
解决Google登录取消后应用无响应的问题
看起来你遇到的问题核心是用户取消登录流后的错误处理逻辑不完善,导致主线程阻塞或者视图控制器无法正常响应。下面是针对性的解决方案,一步步来排查修复:
1. 正确处理取消登录的错误回调
错误码-5(对应GIDSignInErrorCode.canceled)是用户主动取消登录的正常回调,但如果你的错误处理逻辑没有正确收尾,就可能导致应用卡住。确保在回调里专门处理这个错误,并且所有UI操作都放在主线程:
// 如果你用的是新版GIDSignIn的闭包回调(iOS 14+) @IBAction func googleLoginTapped(_ sender: UIButton) { guard let clientID = FirebaseApp.app()?.options.clientID else { return } let configuration = GIDConfiguration(clientID: clientID) // 注意用[weak self]避免循环引用 GIDSignIn.sharedInstance.signIn(withPresenting: self, configuration: configuration) { [weak self] result, error in guard let self = self else { return } if let error = error { let nsError = error as NSError // 专门处理用户取消的情况 if nsError.code == GIDSignInErrorCode.canceled.rawValue { DispatchQueue.main.async { // 只做简单提示,不要执行阻塞操作 let alert = UIAlertController(title: "登录取消", message: "你已取消Google登录", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default)) self.present(alert, animated: true) } return // 直接返回,终止后续错误逻辑 } else { // 处理其他登录错误 print("Error signing in: \(error.localizedDescription)") DispatchQueue.main.async { // 给用户显示其他错误提示 } } return } // 登录成功的正常逻辑(比如传给Firebase认证) guard let user = result?.user, let idToken = user.idToken?.tokenString else { return } let credential = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: user.accessToken.tokenString) Auth.auth().signIn(with: credential) { authResult, error in if let error = error { print("Firebase认证失败: \(error.localizedDescription)") return } // 跳转首页或其他逻辑 self.navigationController?.pushViewController(HomeViewController(), animated: true) } } }
2. 确保URL回调正确转发
不管你用的是AppDelegate还是SceneDelegate,都要正确处理Google登录的URL回调,否则可能导致登录流结束后应用状态异常:
对于AppDelegate:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { return GIDSignIn.sharedInstance.handle(url) }
对于SceneDelegate(iOS 13+):
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { guard let url = URLContexts.first?.url else { return } _ = GIDSignIn.sharedInstance.handle(url) }
3. 排查主线程阻塞问题
应用无响应大概率是主线程被阻塞了,检查你的错误处理逻辑里有没有:
- 同步执行耗时操作(比如网络请求、大量计算)
- 没有用
DispatchQueue.main.async更新UI - 无限循环或死锁的代码
4. 避免循环引用
如果你的闭包没有用[weak self],会导致LoginViewController无法被释放,进而出现内存泄漏和无响应的情况。一定要在涉及视图控制器的闭包里加上弱引用。
按照上面的步骤调整后,用户取消登录时应该只会弹出提示,之后应用能正常响应其他操作。
内容的提问来源于stack exchange,提问作者LampPost
相关产品推荐
相关产品推荐

