[英]Access ViewController from AppDelegate in Xcode 11.5 (firebase google sign in)
我正在為玩具應用程序實施 Firebase Google 登錄。 Google 登錄后,應用程序假設從 SignInViewController 移動到 HomePageViewController。 根據 firebase 指令( https://firebase.google.com/docs/auth/ios/google-signin ),1. GDSignInButton 安裝在 SignInViewController 2. AppDelegate 應該實現 GDSignInDelegate 的 sign()。
在 AppDelegate 中的 sign() 結束之前,我應該如何告訴 SignInViewController,你可以移動到 HomePageViewController。 我已成功按照說明完成登錄。但我不知道如何在 AppDelegate 中轉換視圖控制器。
請注意,在 Xcode 11.5 中,有一個 SceneDelegate,它擁有一個 window,該 window 在舊版本中曾經屬於 AppDelegate。 所以我們無法在 AppDelegate 中獲得對包含視圖控制器的 Window 的引用。 提前致謝!
這是我在 iOS 13 中執行此操作的代碼:
import Firebase
import GoogleSignIn
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
// configure de firebase app
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
return true
}
// other methods in app delegate
@available(iOS 9.0, *)
func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
return GIDSignIn.sharedInstance().handle(url)
}
}
import Firebase
import GoogleSignIn
import FirebaseAuth
// conform to the google sign in delegate
class SceneDelegate: UIResponder, UIWindowSceneDelegate, GIDSignInDelegate {
var window: UIWindow?
// when the app launches, it checks if the user is signed in, and redirect to the correct view controller
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let windowScene = scene as? UIWindowScene {
self.window = UIWindow(windowScene: windowScene)
if Auth.auth().currentUser != nil {
// redirect to the home controller
self.window!.rootViewController = storyboard.instantiateViewController(withIdentifier: "HomeTabBarController")
self.window!.makeKeyAndVisible()
} else {
// redirect to the login controller
self.window!.rootViewController = storyboard.instantiateViewController(withIdentifier: "LoginViewController")
self.window!.makeKeyAndVisible()
}
}
GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
GIDSignIn.sharedInstance().delegate = self
}
// handle the sign in to redirect to the home controller
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
if error != nil {
return
}
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(error.localizedDescription)
return
}
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// redirect the user to the home controller
self.window!.rootViewController = storyboard.instantiateViewController(withIdentifier: "HomeTabBarController")
self.window!.makeKeyAndVisible()
}
}
func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
// Perform any operations when the user disconnects from app here.
// ...
}
}
如果您的項目使用SceneDelegate
,那么您必須使用以下代碼來獲取密鑰 window。 從keyWindow
您可以使用 .rootViewController 訪問.rootViewController
並將其向下轉換為MyViewController
並相應地訪問它。
let keyWindow = UIApplication.shared.connectedScenes
.filter({$0.activationState == .foregroundActive})
.map({$0 as? UIWindowScene})
.compactMap({$0})
.first?.windows
.filter({$0.isKeyWindow}).first
let myViewContorller = keyWindow?.rootViewController as? MyViewController
在 appDelegate 中:-
可以通過將其作為 RootViewController 傳遞
func application(application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [NSObject: AnyObject]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let viewController : UIViewController = storyBoard.instantiateViewControllerWithIdentifier(“InitialControllerID”) as InitialViewController
self.window?.rootViewController = viewController
self.window?.makeKeyAndVisible()
return true
}
或者,如果 rootViewController 是 UINavigation Controller 類型,那么將您的主屏幕推到它上面:-
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let rootViewController = self.window!.rootViewController as! UINavigationController
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = mainStoryboard.instantiateViewController(withIdentifier: “InitialControllerID") as! InitialViewController
rootViewController.pushViewController(viewController, animated: true)
return true
}
或者
在這篇文章的基礎上:- “ https://www.dev2qa.com/how-to-set-application-root-view-controller-programmatically-in-xcode-11/ ”
For iOS 13
In SceneDelegate.swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options `connectionOptions: UIScene.ConnectionOptions) {`
// If this scene's self.window is nil then set a new UIWindow object to it.
self.window = self.window ?? UIWindow()
// Set this scene's window's background color.
self.window!.backgroundColor = UIColor.red
// Create a ViewController object and set it as the scene's window's root view controller.
self.window!.rootViewController = ViewController()
// Make this scene's window be visible.
self.window!.makeKeyAndVisible()
guard scene is UIWindowScene else { return }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.