Доступ к ViewController из AppDelegate в Xcode 11.5 (вход в firebase google) - PullRequest
0 голосов
/ 26 мая 2020

Я использую Firebase Google Sign in для игрушечного приложения. После входа в систему Google приложение должно перейти от SignInViewController к HomePageViewController. Согласно инструкциям firebase (https://firebase.google.com/docs/auth/ios/google-signin), 1. GDSignInButton установлен в SignInViewController 2. AppDelegate должен реализовывать sign () GDSignInDelegate.

Перед концом sign (), который находится в AppDelegate, как мне сообщить SignInViewController, что вы можете перейти к HomePageViewController. Я успешно выполнил инструкции и завершил вход в систему. Но я не знаю, как перенести контроллеры представления в AppDelegate.

Обратите внимание, что в Xcode 11.5 есть SceneDelegate, которому принадлежит окно, которое раньше принадлежало AppDelegate в более старой версии. Таким образом, мы не можем получить ссылку на Window, которое содержит контроллеры представления, в AppDelegate. Заранее спасибо!

Моя проблема решена. Спасибо тем, кто помогал! Но мой вопрос остается: представьте, что вы находитесь в AppDelegate, как вы общаетесь (получаете доступ) к своим представлениям?

Ответы [ 3 ]

1 голос
/ 28 мая 2020

Вот мой код для этого в iOS 13:

AppDelegate.swift

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)
    }
}

SceneDelegate.swift

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.
        // ...

    }


}
0 голосов
/ 27 мая 2020

В 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, тогда pu sh ваш домашний экран поверх него, например: -

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 }
}
0 голосов
/ 26 мая 2020

Если в вашем проекте используется SceneDelegate, вы должны использовать следующий код, чтобы перейти к ключевому окну. Из 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
...