我需要从Firebase数据库中获取数据,并且我的功能由两个循环(一个在另一个内部)表示。 代码如下:
// THE 1ST LOOP FETCHING THE LIST OF EQUIPMENT
self.db.collection("fl_content")
.whereField("_fl_meta_.schema", isEqualTo: "equipment")
.whereField("active", isEqualTo: true)
.getDocuments() {
(querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)");
} else {
var imagesToFetch: [String : String] = [:]
for equipmentDocument in querySnapshot!.documents {
if
let name = equipmentDocument.data()["name"] as? String, let images = equipmentDocument.data()["image"] as? [DocumentReference], let active = equipmentDocument.data()["default"] as? Bool, let def = equipmentDocument.data()["default"] as? Bool {
var documentData: [String: Any] = [:]
documentData["name"] = name
documentData["active"] = active
documentData["default"] = def
documentData["image"] = images[0].documentID
equipmentData[equipmentDocument.documentID] = documentData
if images.indices.contains(0) {
if FileManager.fileExists(path: "\(Constants.fileSavePath)\(images[0].documentID)") {
self.toolList.append(
Equipment(
fbid: equipmentDocument.documentID,
name: name,
image: (documentData["image"] != nil) ? FileManager.fileToUIImage(path: images[0].documentID) : nil,
active: active,
def: def)
)
} else {
imagesToFetch[equipmentDocument.documentID] = images[0].documentID
}
}
} else {
print("No 'name' or 'image' found for this journey")
}
}
// got all data, let's get file paths and check if files exist
if(!imagesToFetch.isEmpty) {
// fetching paths to the images
self.db.collection("fl_files").whereField("_fl_meta_.docId", in: Array(imagesToFetch.values)).getDocuments() {
(querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)");
} else {
for imageDocument in querySnapshot!.documents {
// Getting file paths from Firebase .....
**HERE COMES THE 2ND LOOP FETCHING THE IMAGES FOR EACH GEAR**
}
}
}
}
}
}
问题是我需要形成一个数组并将这个数组(当所有请求都完成并且获取数据时)传递给下一个View。但是我不知道如何判断是否所有Firebase请求都已处理。
如果我将代码放置在这2个循环之后,则可能在获取所有数据之前执行了代码,对吗?一些请求可能仍在进行中
那我如何保证包含数据的阵列已经准备好?
当此类数据用于UI更新时,我真的不在乎所有操作都完成了,因为UI订阅了我的“已发布”变量,但是在这种情况下,我希望能够检测到何时所有请求完成并获取数据。
做到这一点的最佳方法是什么?我应该使用计数器检查所有请求是否已完成并使用完成处理程序吗?
答案 0 :(得分:1)
您可以使用DispatchGroup
。使用enter()
和leave()
函数来确定新任务何时开始和完成。然后,使用notify()
函数来执行调度组为空(这取决于计数输入和离开操作来决定)时需要做的所有事情。