Firebase & Swift - отложить изменение ViewController, пока данные не будут прочитаны - PullRequest
1 голос
/ 03 мая 2019

Я ввел логин для загрузки данных из базы данных в режиме реального времени каждый раз, когда пользователь входит в систему. Когда пользователь успешно вошел в систему, данные читаются - проблема в том, что AppDelegate меняет ViewController быстрее, чем данные читаются. Поэтому ничего не будет отображаться, пока приложение снова не закроется.

Есть ли способ отложить изменение представления до считывания данных?

didFinishLaunchingOptions() внутри AppDelegate:

let authListener = Auth.auth().addStateDidChangeListener { auth, user in

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

    if user != nil {
        let controller = storyboard.instantiateViewController(withIdentifier: "RootPageViewController") as! RootPageViewController
        self.window?.rootViewController = controller
        self.window?.makeKeyAndVisible()
    } else {
        let vc = storyboard.instantiateViewController(withIdentifier: "SettingsTableViewController") as! SettingsTableViewController
        vc.runResetData()

        let controller = storyboard.instantiateViewController(withIdentifier: "ProfileViewController") as! ProfileViewController
        self.window?.rootViewController = controller
        self.window?.makeKeyAndVisible()
    }
}

LoginViewController:

@IBAction func login(_ sender: Any) {
    guard let email = emailInput.text else { return }
    guard let password = passwordInput.text else { return }

    Auth.auth().signIn(withEmail: email, password: password) { user, error in
        if error == nil && user != nil {
            self.readData()
            self.dismiss(animated: false, completion: nil)
        } else {
            print("Error logging in: ", error!.localizedDescription)

            let alert = UIAlertController(title: "Fehler beim Einloggen", message: error!.localizedDescription, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Verstanden", style: .default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
    }
} 

func readData() {
    guard let uid = Auth.auth().currentUser?.uid else { return }
    let databaseRef = Database.database().reference()

    databaseRef.child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in

        let value = snapshot.value as? NSDictionary
        let monthlyStartKmData = value?["monthlyStartKm"] as? Int ?? 0
        let currentKmData = value?["currentKm"] as? Int ?? 0
        ...


        startKm = monthlyStartKmData
        currentKm = currentKmData
        ...


    }) { (error) in
        print(error.localizedDescription)
    }

}

Ответы [ 2 ]

2 голосов
/ 03 мая 2019

Нет, вы не можете, так как вызов прослушивания является асинхронным, поэтому он запускается с задержкой, пока установлен rootVC, вам нужно показать загрузчик типа

 let vc = UIViewController()
 vc.view.backgroundColor = .red
 self.window?.rootViewController = vc
 self.window?.makeKeyAndVisible()    
 let authListener = Auth.auth().addStateDidChangeListener { auth, user in 
   .....
 }

Внутри AppDelegate

if FIRAuth.auth().currentUser != nil {
   // go to home , if you went before you should have km month values cached 
}
else {
  // go to login
}
0 голосов
/ 04 мая 2019

Существует возможность отложить изменение представления, пока Firebase не сможет загрузить свои данные:

databaseRef.observeSingleEvent

Рабочий код:

let authListener = Auth.auth().addStateDidChangeListener { auth, user in
            let databaseRef = Database.database().reference()

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

            if user != nil {
                databaseRef.observeSingleEvent(of: .value, with: { snap in
                    let controller = storyboard.instantiateViewController(withIdentifier: "RootPageViewController") as! RootPageViewController
                    self.window?.rootViewController = controller
                    self.window?.makeKeyAndVisible()
                })
            } else {
                let vc = storyboard.instantiateViewController(withIdentifier: "SettingsTableViewController") as! SettingsTableViewController
                vc.runResetData()

                let controller = storyboard.instantiateViewController(withIdentifier: "ProfileViewController") as! ProfileViewController
                self.window?.rootViewController = controller
                self.window?.makeKeyAndVisible()
            }

        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...