我的故事板流程如下:
LaunchViewController -> LoginViewController(with google sign in) -> LocationViewController(for location permission) -> TabBarController -> NavigationController -> If `user logged in and allow to location permission` it will show RestaurantsTableViewController -> DetailViewController
个餐厅。
当用户进入LoginScreen
时,会弹出google登录警报,当用户允许时,会显示google登录屏幕。成功登录google的自定义登录屏幕后,我应该显示或执行我的LocationViewController
。
我尝试了这个Swift: Go to other view controller after Google Sign In和这个Pushing a view controller using Swift 4 after Google Sign In的答案,但没有解决。
我上次尝试的代码如下:
LoginViewController
import UIKit
import Firebase
import GoogleSignIn
class LoginViewController: UIViewController, GIDSignInUIDelegate {
override func viewDidLoad() {
super.viewDidLoad()
GIDSignIn.sharedInstance()?.clientID = MyConstants.googleClientID
GIDSignIn.sharedInstance().uiDelegate = (self as! GIDSignInUIDelegate)
GIDSignIn.sharedInstance().signIn()
NetworkManager.isUnreachable { _ in
self.showOfflinePage()
}
}
@IBAction func googleSignInTapped(_ sender: Any) { }
private func showOfflinePage() -> Void {
DispatchQueue.main.async {
self.performSegue(withIdentifier: "NetworkUnavailable", sender: self)
}
}
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
if let error = error {
print("Firebase sign in error: \(error)")
return
}
在 else
阻止之后,我尝试显示或执行视图控制器
else {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let nav = storyboard.instantiateViewController(withIdentifier: "NavigationController") as! UINavigationController
self.present(nav, animated: false, completion: nil)
}
guard let authentication = user.authentication else { return }
let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
accessToken: authentication.accessToken)
Auth.auth().signIn(with: credential) { (authResult, error) in
if let error = error {
print("Firebase sign in error: \(error)")
return
} else {
let locationViewController = self.storyboard?.instantiateViewController(withIdentifier: "LocationViewController")
self.present(locationViewController!, animated: true, completion: nil)
}
}
}
}
在 AppDelegate
中,我尝试过:
extension AppDelegate: GIDSignInDelegate {
//MARK: - Firebase
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return GIDSignIn.sharedInstance().handle(url as URL?,
sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
annotation: options[UIApplication.OpenURLOptionsKey.annotation])
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return GIDSignIn.sharedInstance().handle(url,
sourceApplication: sourceApplication,
annotation: annotation)
}
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!,
withError error: Error!) {
if let error = error {
print("\(error.localizedDescription)")
} else {
let userId = user.userID
let idToken = user.authentication.idToken
let fullName = user.profile.name
let givenName = user.profile.givenName
let familyName = user.profile.familyName
let email = user.profile.email
}
}
func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!,
withError error: Error!) { }
}
在didFinishLaunchingWithOptions
中,将rootViewController
设置为LoginViewController:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
self.window.rootViewController = storyboard.instantiateViewController(withIdentifier: "LoginViewController") as? LoginViewController
Firebase.configure()
GIDSignIn.sharedInstance().clientID = MyConstants.googleClientID
GIDSignIn.sharedInstance().delegate = self
}
如果我尝试使用present()
函数,则不会执行任何操作:
否则,导航控制器出现此错误:
whose view is not in the window hierarchy