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

如何在函数外部访问Google提供的变量?跨VC获取emailAddress

解决在其他ViewController访问LoginController中变量的问题

你的核心问题是**emailAddress是闭包内的局部变量,仅在当前作用域有效**,而且全局定义的login实例和实际显示的LoginController是两个不同对象,导致无法获取正确的值。以下是具体修复方案:

1. 将局部变量改为类的实例属性

把原本在闭包里定义的用户信息变量,移到LoginController类的顶层作为实例属性,让外部可以通过实例访问:

import UIKit
import GoogleSignIn

class LoginController: UIViewController {
    
    @IBOutlet weak var signInButton: GIDSignInButton!
    
    let signInConfig = GIDConfiguration(clientID: "12345-abcdef.apps.googleusercontent.com")
    
    // 声明为实例属性,外部可访问
    var emailAddress: String?
    var fullName: String?
    var givenName: String?
    var familyName: String?
    var profilePicUrl: URL?
    
    @IBAction func signIn(_ sender: Any)  {
        GIDSignIn.sharedInstance.signIn(with: signInConfig, presenting: self) { user, error in
            guard error == nil else { return }
            guard let user = user else { return }

            // 给实例属性赋值(注意使用self.)
            self.emailAddress = user.profile?.email
            self.fullName = user.profile?.name
            self.givenName = user.profile?.givenName
            self.familyName = user.profile?.familyName
            self.profilePicUrl = user.profile?.imageURL(withDimension: 320)
            
            print("Sign in Successful")
            print(self.fullName!)
            print(self.givenName!)
            print(self.familyName!)
            print(self.emailAddress!)
            print(self.profilePicUrl!)
            
            // 修复跳转错误:同时调用push和present会导致异常,保留一种方式即可
            let vc = self.storyboard?.instantiateViewController(withIdentifier: "NavigationViewController") as! UINavigationController
            self.present(vc, animated: true, completion: nil)
        }
    }
}

2. 确保访问的是正确的LoginController实例

你当前定义的全局let login = LoginController(),和通过storyboard实例化的LoginController是两个独立对象,直接用login.emailAddress会得到nil。提供两种解决方式:

方式一:使用单例模式(适合全局访问)

修改LoginController为单例,确保整个APP只有一个实例:

class LoginController: UIViewController {
    // 全局单例实例
    static let shared = LoginController()
    
    // 其他属性和方法保持不变...
}

之后在其他ViewController中,直接通过LoginController.shared.emailAddress访问变量。

方式二:跳转时直接传值(适合页面间定向传递)

如果仅需要在跳转后的页面使用该值,直接在跳转时传递:

// 在LoginController的signIn闭包中
let navVC = self.storyboard?.instantiateViewController(withIdentifier: "NavigationViewController") as! UINavigationController
// 假设导航控制器的根VC是MainViewController
if let mainVC = navVC.viewControllers.first as? MainViewController {
    mainVC.userEmail = self.emailAddress
    mainVC.userFullName = self.fullName
    // 传递其他需要的属性
}
self.present(navVC, animated: true, completion: nil)

然后在MainViewController中声明对应属性:

class MainViewController: UIViewController {
    var userEmail: String?
    var userFullName: String?
    
    // 后续可直接使用这些变量
}

额外注意点

  • 原代码中同时调用pushViewController和present会导致重复跳转,必须删除其中一个。
  • 访问可选类型变量时,建议用if let可选绑定替代强制解包(!),避免因nil引发崩溃。

内容的提问来源于stack exchange,提问作者James Woollcott

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:45:33