处理 tableView 中的异步 Firestore 数据读取 - iOS [英] Handling asynchronous Firestore data reading in tableView - iOS

查看:17
本文介绍了处理 tableView 中的异步 Firestore 数据读取 - iOS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从我的简单 Firestore 数据库中检索数据

I would like to retrieve data from my simple Firestore database

我有这个数据库:

然后我有一个模型类,其中有一个方法负责检索如下所示的数据:

then I have a model class where I have a method responsible for retrieving a data which looks like this:

func getDataFromDatabase() -> [String] {
    var notes: [String] = []
    collectionRef = Firestore.firestore().collection("Notes")

    collectionRef.addSnapshotListener { querySnapshot, error in
            guard let documents = querySnapshot?.documents else {
                print("Error fetching documents: (error!)")
                return
            }
        notes = documents.map { $0["text"]! } as! [String] // text is a field saved in document
            print("inside notes: (notes)")
    }
    print("outside notes: (notes)")
    return notes
}

作为 UI 表示,我有 tableViewController.让我们采取其中一种方法,例如

and as a UI representation I have tableViewController. Let's take one of the methods, for example

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    print("tableview numberOfRowsInSection called")
    return model.getDataFromDatabase().count
}

然后numberOfRows为0,控制台输出为:

Then numberOfRows is 0 and the output in the console is:

我最终在 tableView 中没有单元格.我添加了一个断点,它不会跳转到侦听器内部.

and I am ending up with no cells in tableView. I added a breakpoint and it doesn't jump inside the listener.

即使我有 3 个,他们也有点迟到"了?它们随后被加载.然后 tableView 没有显示任何内容,但控制台说(稍后)有 3 个单元格.

And even though I have 3 of them, they are kinda "late"? They are loaded afterwards. And then the tableView doesn't show anything but console says (later) that there are 3 cells.

如果需要,还有我显示单元格名称的方法:

If needed, there is also my method for showing the cells names:

 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    print("Cells")
    let cell = tableView.dequeueReusableCell(withIdentifier: "firstCell", for: indexPath)

    cell.textLabel!.text = String(model.getDataFromDatabase()[indexPath.row].prefix(30))

    return cell
}

但是这个方法甚至没有加载(控制台中没有打印)并且这个方法写在带有 numberOfRowsInSection 的方法下面.

but this method is not even loaded (no print in the console) and this method is written below the method with numberOfRowsInSection.

我也有 2 个错误(我不知道为什么每一行都写了两次),它们是:

I have also 2 errors (I don't know why each line is written twice) and these are:

但我认为这与问题无关.

but I don't think it has something to do with the problem.

感谢您的帮助!

推荐答案

正如@Galo Torres Sevilla 提到的,addSnapshotListener 方法是异步的,您需要将完成处理程序添加到您的 getDataFromDatabase() 函数.

As @Galo Torres Sevilla mentioned, addSnapshotListener method is async and you need to add completion handler to your getDataFromDatabase() function.

在您的代码中进行以下更改:

Make following changes in your code:

  1. 为笔记声明全局变量.

  1. Declare Global variable for notes.

var list_notes = [String]()

  • getDataFromDatabase() 方法添加完成处理程序.

  • Add completion handler to getDataFromDatabase() method.

    func getDataFromDatabase(callback: @escaping([String]) -> Void) {
        var notes: [String] = []
        collectionRef = Firestore.firestore().collection("Notes")
    
        collectionRef.addSnapshotListener { querySnapshot, error in
            guard let documents = querySnapshot?.documents else {
                print("Error fetching documents: (error!)")
                return
            }
            notes = documents.map { $0["text"]! } as! [String] // text is a field saved in document
            print("inside notes: (notes)")
    
            callback(notes)
        }
    }
    

  • 最后,在您想要获取笔记的适当位置调用函数并将检索到的笔记分配给您的全局变量并重新加载TableView,如下所示:

    self.getDataFromDatabase { (list_notes) in
        self.list_notes = list_notes
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }
    

  • TableView 的变化:

    Changes in TableView:

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("tableview numberOfRowsInSection called")
        return self.list_notes.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print("Cells")
        let cell = tableView.dequeueReusableCell(withIdentifier: "firstCell", for: indexPath)
    
        cell.textLabel!.text = String(self.list_notes[indexPath.row].prefix(30))
    
        return cell
    }
    

    这篇关于处理 tableView 中的异步 Firestore 数据读取 - iOS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆