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

UIKit集成Google登录后如何跳转主界面并持久化登录状态

iOS Google Sign-In 登录流实现方案

问题现状

你在独立登录页集成Google Sign-In后遇到两个问题:

  • 登录后主界面以模态形式弹出,用户可轻易返回登录页打乱流程
  • 每次应用冷启动都需要重复登录,无法记住登录状态

当前错误实现代码如下:

@IBAction func signIn(_ sender: Any) {
let signInConfig = GIDConfiguration.init(clientID: "xyz.apps.googleusercontent.com")
GIDSignIn.sharedInstance.signIn(with: signInConfig, presenting: self) { user, error in
  guard error == nil else { return }

  // If sign in succeeded, display the app's main content View.
    let vc = self.storyboard?.instantiateViewController(withIdentifier: "scanReceiptsViewController") as! ViewController
    self.navigationController?.pushViewController(vc, animated: true)
    self.present(vc, animated: true, completion: nil)
}

}

问题根源是同时调用了pushViewController和present两种冲突的跳转方式,且没有做启动时的登录态持久化判断。
你的Storyboard结构参考:
My Storyboard


具体实现步骤

1. 修复登录成功跳转逻辑

不要用push或模态弹出的方式跳主界面,直接切换App窗口的根控制器为主Navigation Controller,登录页会被系统自动回收,用户不存在返回登录页的路径。

  1. 打开Storyboard,选中你的主Navigation Controller,在Identity检查器里给它设置Storyboard ID,比如MainNavigationController
  2. 把登录成功的回调代码替换为如下内容:
@IBAction func signIn(_ sender: Any) {
    let signInConfig = GIDConfiguration(clientID: "xyz.apps.googleusercontent.com")
    GIDSignIn.sharedInstance.signIn(with: signInConfig, presenting: self) { user, error in
        guard error == nil, let validUser = user else { return }
        
        // 实例化主导航控制器
        let mainStoryboard = UIStoryboard(name: "Main", bundle: .main)
        guard let mainNav = mainStoryboard.instantiateViewController(withIdentifier: "MainNavigationController") as? UINavigationController,
              let window = UIApplication.shared.windows.first else {
            return
        }
        
        // 如果需要直接进入小票扫描页,直接设置导航栈的根页面,不需要push
        if let scanVC = mainStoryboard.instantiateViewController(withIdentifier: "scanReceiptsViewController") as? ViewController {
            mainNav.viewControllers = [scanVC]
        }
        
        // 切换根控制器,加淡入过渡动画避免生硬
        window.rootViewController = mainNav
        UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: nil)
    }
}

2. 实现启动自动登录逻辑

Google Sign-In会本地缓存用户登录凭证,你只需要在App启动阶段检查是否有有效历史登录态,有就直接进主界面,没有才展示登录页。

  • 如果项目用了SceneDelegate(iOS13+默认模板),把下面的代码写到scene(_:willConnectTo:options:)方法里
  • 如果是老版本项目没有SceneDelegate,就把逻辑写到AppDelegate的application(_:didFinishLaunchingWithOptions:)方法里

参考代码:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = scene as? UIWindowScene else { return }
    let window = UIWindow(windowScene: windowScene)
    let mainStoryboard = UIStoryboard(name: "Main", bundle: .main)
    
    // 检查是否有历史登录记录
    if GIDSignIn.sharedInstance.hasPreviousSignIn() {
        // 尝试恢复登录态
        GIDSignIn.sharedInstance.restorePreviousSignIn { [weak self] user, error in
            if error == nil, let _ = user {
                // 登录态有效,直接加载主界面
                guard let mainNav = mainStoryboard.instantiateViewController(withIdentifier: "MainNavigationController") as? UINavigationController else {
                    return
                }
                window.rootViewController = mainNav
            } else {
                // 登录态失效,加载登录页(替换成你自己登录页的Storyboard ID)
                let loginVC = mainStoryboard.instantiateViewController(withIdentifier: "LoginViewController")
                window.rootViewController = loginVC
            }
            window.makeKeyAndVisible()
            self?.window = window
        }
    } else {
        // 无历史登录记录,加载登录页
        let loginVC = mainStoryboard.instantiateViewController(withIdentifier: "LoginViewController")
        window.rootViewController = loginVC
        window.makeKeyAndVisible()
        self.window = window
    }
}

注意事项

  • 所有代码里用到的Storyboard ID必须和你在Storyboard里设置的完全一致,否则会触发运行时崩溃
  • 后续如果要实现登出功能,先调用GIDSignIn.sharedInstance.signOut()清除本地登录态,再把根控制器切回登录页即可
  • 不要混用push、present两种方式做登录到主界面的跳转,切换根控制器是登录流最稳妥的实现方式,不会出现导航栈混乱的问题

内容的提问来源于stack exchange,提问作者Abdelrahman Hafrag

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:12:21