Ios 从视图控制器中的应用程序委托访问变量

Ios 从视图控制器中的应用程序委托访问变量,ios,swift,swift3,Ios,Swift,Swift3,我正在我的应用程序上实施谷歌登录,我需要访问用户ID和名/姓。存储该数据的变量位于应用程序委托中。我搜索了互联网内外寻找如何在Swift 3中做到这一点,但绝对没有 以下是应用程序代理(至少是重要的部分): 在视图控制器中,我正在调用App delegate并尝试接收数据,但它给了我一个错误提示:“实例成员'User ID'不能用于'AppDelegate'类型” 我还尝试在=AppDelegate.userID中用delegate切换AppDelegate,但它给出了相同的错误。发生了什么事?

我正在我的应用程序上实施谷歌登录,我需要访问用户ID和名/姓。存储该数据的变量位于应用程序委托中。我搜索了互联网内外寻找如何在Swift 3中做到这一点,但绝对没有

以下是应用程序代理(至少是重要的部分):

在视图控制器中,我正在调用App delegate并尝试接收数据,但它给了我一个错误提示:“实例成员'User ID'不能用于'AppDelegate'类型”


我还尝试在=AppDelegate.userID中用delegate切换AppDelegate,但它给出了相同的错误。发生了什么事?

错误消息告诉您,
属性初始值设定项在“self”可用之前运行

也许您应该在
viewDidLoad

let delegate = UIApplication.shared.delegate as! AppDelegate
var user: String?
var firstName: String?
var lastName: String?

override func viewDidLoad() {
    super.viewDidLoad()

    user = delegate.userID
    firstName = delegate.givenName
    lastName = delegate.familyName
}

AppDelegate
是类。您需要的是应用程序的委托的
AppDelegate
实例。此外,您不能使用声明的
委托
常量来设置其他实例成员的值,因为它本身也是实例成员

我喜欢在
AppDelegate
中实现如下函数:

static func shared() -> AppDelegate {
    return UIApplication.shared.delegate as! AppDelegate
}
public class var shared: AppDelegate {
    return UIApplication.shared.delegate as! AppDelegate
}
然后我可以从其他地方这样称呼它:

let firstName = AppDelegate.shared().givenName

另一个选项是使用您定义的
委托
属性设置这些属性的值,但稍后在
视图加载
中进行设置,如阿尔文的回答所建议的那样。

您还可以制作类似于UIApplication.shared的内容。。。。然后,您必须将其添加到AppDelegates:

open class var shared: AppDelegate {
    get {
        return UIApplication.shared.delegate as! AppDelegate
    }
}
或者像这样:

static func shared() -> AppDelegate {
    return UIApplication.shared.delegate as! AppDelegate
}
public class var shared: AppDelegate {
    return UIApplication.shared.delegate as! AppDelegate
}
比Swift 3.x语法更好:)


干杯

更新:您不需要访问GoogleSignIn的Appdelegate。在按钮操作中使用以下代码

 @IBAction func loginWithGoogle(_ sender: Any) {
    GIDSignIn.sharedInstance().uiDelegate = self
    GIDSignIn.sharedInstance().signIn()
    //Be sure that you are signed-in
    if(GIDSignIn.sharedInstance().hasAuthInKeychain()){
        print("Signed-in")
        //Use currentUser attribute.
        print(GIDSignIn.sharedInstance().currentUser.profile.email)
    }
}

你不应该这样做。您应该具有处理登录的适当抽象。应用程序委托应为私有类。使用这种共享状态有什么意义?Google登录有方便的方法来处理此问题,用户凭据不应存储在app delegate中。如果需要,可以使用某些类或数据库