Как обрабатывать асинхронное получение пользователя из Firestore в Swift - PullRequest
0 голосов
/ 19 июня 2020

У меня есть приложение Swift, которое использует Firebase для работы с пользователями. У меня также есть класс User с синглтоном для текущего пользователя. Я пытаюсь установить этот синглтон в Scene Delegate до того, как что-нибудь произойдет с ViewControllers в приложении, но у меня возникают проблемы с асинхронным извлечением данных из Firestore. В моем контроллере домашнего представления я пытаюсь установить текст метки с именем текущего пользователя, но получаю сообщение об ошибке, что текущего пользователя нет, поэтому он не был установлен при вызове viewDidLoad. Мой делегат сцены выглядит так:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
        guard let _ = (scene as? UIWindowScene) else { return }

        if let currentUser = Auth.auth().currentUser {

            print("user is logged in")
            print("current user uid: @!", currentUser.uid)


            UserService.getUserData(uid: currentUser.uid) { (data) in
                if let data = data {
                    print(data.keys)
                    let myUser = User(uid: currentUser.uid, data: data)
                    User.setCurrent(myUser)
                    print("User was set")

                    let storyboard = UIStoryboard(name: "Main", bundle: .main)

                    if let initialViewController = storyboard.instantiateInitialViewController() {

                        self.window?.rootViewController = initialViewController
                        self.window?.makeKeyAndVisible()
                    }

                } else {
                    print("Error retrieving user data")
                }
            }

        } else {

            let initialViewController = UIStoryboard.initalViewController(for: .login)
            self.window?.rootViewController = initialViewController
            self.window?.makeKeyAndVisible()

        }

    }

Моя функция getUserData:

static func getUserData(uid: String, _ completion: @escaping (_ data: [String: Any]?) -> Void ) {
        print("getUserData called")
        let userRef = Firestore.firestore().collection(Constants.Firestore.Collections.users)
        let userDocRef = userRef.document(uid)

        userDocRef.getDocument { (document, error) in
            guard let document = document, document.exists else {
                print("document does not exist")
                completion(nil)
                return
            }
            print("code is here")
            completion(document.data())
        }
    }

И мой HomeV C метод viewDidLoad:

override func viewDidLoad() {
        super.viewDidLoad()
        availabilitySwitch.isOn = false
        print("Home view loaded")
        let first = User.current.firstName
        welcomeLabel.text = "Welcome Back, " + first + "!"
        // Do any additional setup after loading the view.

    }

Любая идея как получить данные пользователя до того, как это будет вызвано?

1 Ответ

0 голосов
/ 19 июня 2020

Создайте свойство в HomeVC

var username = ""

и отобразите значение свойства в viewDidLoad, если оно не пустое.

override func viewDidLoad() {
    super.viewDidLoad()
    availabilitySwitch.isOn = false
    print("Home view loaded")
    if !username.isEmpty {
        welcomeLabel.text = "Welcome Back, " + username + "!"
    }
}

В scene(_ scene: UIScene, willConnectTo назначьте имя пользователя после создания экземпляра контроллера представления

...
UserService.getUserData(uid: currentUser.uid) { (data) in
    if let data = data {
        print(data.keys)
        let myUser = User(uid: currentUser.uid, data: data)
        User.setCurrent(myUser)
        print("User was set")

        let storyboard = UIStoryboard(name: "Main", bundle: .main)

        if let initialViewController = storyboard.instantiateInitialViewController() {
            (initialViewController as! HomeVC).username = myUser.firstName
            self.window?.rootViewController = initialViewController
            self.window?.makeKeyAndVisible()
        }

    } else {
        print("Error retrieving user data")
    }
}
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...