在TableView中处理异步Firestore数据读取-iOS [英] Handling asynchronous Firestore data reading in tableView - 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:
-
为注释声明全局变量.
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屋!