【问题标题】:How to wait for the result of a database read in swift?如何等待快速读取数据库的结果?
【发布时间】:2021-08-17 00:30:36
【问题描述】:

在我的应用程序中,我使用 Firebase 实时数据库来存储有关用户的数据。我想确保当我读取这些数据以在视图中显示它(例如他们的昵称)时,在显示它之前已经完成了读取。让我解释一下:

//Initialization of user properties
    static func initUsers(){
        let usersref = dbRef.child("Users").child(userId!)
        usersref.observeSingleEvent(of: .value) { (DataSnapshot) in
            if let infos = DataSnapshot.value as? [String : Any]{
                self.username = infos["username"] as! Int
                 
                //The VC is notified that the data has been recovered
                let name = Notification.Name(rawValue: "dataRetrieved")
                let notification = Notification(name: name)
                NotificationCenter.default.post(notification)
            }
        }
    }

这是在模型中运行并在用户登录时读取用户数据的代码。

var isFirstAppearance = true
 
override func viewDidLoad() {
        super.viewDidLoad()
         
        //We initialise the properties associated with the user
        Users.initUsers()
    }
     
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if isFirstAppearance {
            let name = Notification.Name(rawValue: "dataRetrieved")
            NotificationCenter.default.addObserver(self, selector: #selector(registerDataToView), name: name, object: nil)
            isFirstAppearance = false
        }
        else{
            registerDataToView()
        }
    }
 
    //The user's data is assigned to the view
    @objc func registerDataToView(){
        usernameLabel.text = String(Users.username)
    }

我们在 VC 中,当视图加载时,我们在 viewDidLoad 中调用 initUsers。在 viewWillAppear 中,如果这是我们第一次加载视图,那么我们创建一个侦听器,如果数据库中的读取完成,它会调用 registerDataToView。否则我们只需调用 registerDataToView (这是在我们返回此 VC 时更新标签)。

我想知道是否有可能,例如当我们的连接非常糟糕时,侦听器不会拦截 dataRetrieved 通知,因此我的 UI 只显示默认文本?还是耳机在继续之前等待接收通知?

如果不等待,那么在初始化标签之前如何等待数据库读取完成?

感谢您的宝贵时间 :)

【问题讨论】:

    标签: ios swift multithreading firebase-realtime-database


    【解决方案1】:

    别等了。永远不要等待。告诉接收者数据可用完成处理程序

    static func initUsers(completion: @escaping (Bool) -> Void) {
        let usersref = dbRef.child("Users").child(userId!)
        usersref.observeSingleEvent(of: .value) { (DataSnapshot) in
            if let infos = DataSnapshot.value as? [String : Any]{
                self.username = infos["username"] as! Int
                completion(true)
                return
            }
            completion(false)
        }
        
    }
    

    并使用它

    override func viewDidLoad() {
        super.viewDidLoad()
         
        //We initialise the properties associated with the user
        Users.initUsers { [unowned self] result in
            if result (
              // user is available 
            } else {
              // user is not available 
            }
        }
    }
    

    【讨论】:

    • 谢谢,但是如果用户连接不好,我如何让他等待数据被读取,以便我可以在视图中显示它。否则 UI 将不完整。如果阅读需要时间,我曾想过将相关标签隐藏起来,当阅读完成时,我会用相关数据显示它们。这是一个好的解决方案吗?
    猜你喜欢
    • 2016-05-24
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 2023-02-03
    • 2019-07-25
    相关资源
    最近更新 更多