我有一个视图控制器,列出了Firestore数据库中的数据。在firestore集合中,我有一堆文档,其信息如列表所示,还有一个名为order
的文档,其中包含一个字段,该字段是按希望显示的顺序排列的字符串数组。我的代码抓住了这个:
self.db.collection("officers").document(school).collection(grade).document("order").getDocument {(document, error) in
if let document = document, document.exists {
self.officerNames = (document.data()!["order"] as! Array<String>)
,然后应该使用数组order
(officerNames
)中的字符串来查询同一集合中的文档(所有文档都具有不同的role
,因此只会快照中的一个文档),并以与order
(officerNames
)中的文档相同的顺序显示它们。
for item in 1...self.officerNames.count {
self.db.collection("officers").document(school).collection(grade).whereField("role", isEqualTo: self.officerNames[item-1]).getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
let officerMessage = document.data()["agenda"] as! String
let officerInfo = document.data()["short"] as! String
(a bunch of code here using that ^ ^ and due to the color I need item to be an integer)
}
}
}
}
我知道,如果我尝试在item
之前打印self.collection("officers").....
,数字将加一,但是如果我在for document in querySnapshot.....
中进行打印,则它们将全部乱序,这意味着某些文档已加载得比别人快。我已经读过Swift中的Async函数(尽管我确实在JavaScript中使用过这些函数),但实际上对如何使用它们感到困惑,希望有一种更简单的方法可以做到这一点。在再次遍历循环之前,我可以等待任何方法来确保已加载并分析了先前的文档吗?
答案 0 :(得分:0)
老实说,您可能想检查一下数据结构,看是否可以创建一个不需要多个查询的数据结构。我还不太清楚您的数据结构是什么,但是如果您更新问题以包含它,我可以为如何重构提供一些建议,这样您就不必执行2个不同的get
请求。>
话虽这么说,由于Swift没有像JS这样的承诺,所以很难保证数据井井有条。正如我在this blog中所写,在大多数情况下,闭包都可以正常工作。但是它们仍然不会在异步调用数组中保留顺序。假设您使用某个数组存储警官的数据,则可以通过为每个数组指定一个默认值来预先声明数组的大小。看起来像这样:
var officerArray = [Officer](repeating:Officer(), count: self.officerNames.count)
当然,这取决于您使用哪种对象填充它。在这种情况下,我正在使用一些通用的Officer
对象。
然后,不要将新创建的Officer
对象(或任何您要调用的对象)附加到数组的末尾,而是将其值添加到数组中的特定位置。
for item in 1...self.officerNames.count {
self.db.collection("officers").document(school).collection(grade).whereField("role", isEqualTo: self.officerNames[item-1]).getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
let officerMessage = document.data()["agenda"] as! String
let officerInfo = document.data()["short"] as! String
// etc
officerArray[self.officerNames.count-1] = Officer(officerMessage: officerMessage, officerInfo: officerInfo) // or however you're instantiating your objects
}
}
}
}
这将保留订单。