在 Google 登录后使用 Swift 4 推送视图控制器

JSD*_*JSD 2 ios firebase swift firebase-authentication

我正在使用 Firebase 和 Swift 4 来开发我的应用程序,但是在 Google 登录完成后我无法推送新的视图控制器。据我所知,我应该将 pushViewController 代码放在 didSignIn 方法中,但该部分在我的 AppDelegate.swift 文件中(因为它实现了 GIDSignInDelegate,根据 Firebase 文档)。

func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
    // ...
    if let error = error {
        // ...
        return
    }

    guard let authentication = user.authentication else { return }
    let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
                                                   accessToken: authentication.accessToken)
    // ...
}
Run Code Online (Sandbox Code Playgroud)

现在,我想在登录完成后推送一个新的视图控制器,使用以下内容:

navigationController?.pushViewController(BrowserViewController(), animated: true)
Run Code Online (Sandbox Code Playgroud)

但是似乎不可能从 AppDelegate 文件中推送 VC,因为那里不存在 navigationController。我在不使用 Storyboards 的情况下以编程方式创建我的视图,所以我也无法执行 segues。

用户使用 Google Sign In 完成登录后,我如何能够展示新的 VC?我是否应该将 didSignInFor 方法移动到实际承载登录按钮的视图控制器(即使文档似乎没有说这是正确的方法)?

小智 6

解决此问题的一种方法是在登录成功时使用通知中心从您的应用程序委托发布通知,然后在承载登录按钮的视图控制器中观察此通知。

这是 swift 4 中的一个例子:

在 didSignInFor 方法中的应用程序委托中:

func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
    // ...
    if let error = error {
        // ...
        return
    }

    guard let authentication = user.authentication else { return }
    let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
                                                   accessToken: authentication.accessToken)
    // ...

    NotificationCenter.default.post(
        name: Notification.Name("SuccessfulSignInNotification"), object: nil, userInfo: nil)
}
Run Code Online (Sandbox Code Playgroud)

在承载登录按钮的 ViewController 中:

 override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(didSignIn), name: NSNotification.Name("SuccessfulSignInNotification"), object: nil)

}

@objc func didSignIn()  {

    // Add your code here to push the new view controller
  navigationController?.pushViewController(BrowserViewController(), animated: true)

}

deinit {
    NotificationCenter.default.removeObserver(self)
}
Run Code Online (Sandbox Code Playgroud)

如果您还想处理失败的登录尝试,您可以使用相同的技巧并发布失败通知,然后在视图控制器中观察它。或者,您也可以对两种情况(成功和失败)使用一个通知,并在每种情况下传递不同的值。