如何在函数外部访问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
相关产品推荐
相关产品推荐

