Reputation: 1168
I need to fetch the data from Firebase database and my function is represented by two loops (one inside another). The code looks like this:
// 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**
}
}
}
}
}
}
The problem is I need to form an array and pass this array (when all requests are done and data is fetched) to the next View. But I don't know how to tell if ALL Firebase requests have been processed.
If I place my code after those 2 loop, it might be executed before all the data is fetched, right? Some requests might still be in progress
So how can I guaranteed that my array with the data is ready?
When this sort of data is used for UI updates I don't really care is all is done as UI is subscribed to my "published" variables, but in this case i wanna be able to detect when ALL REQUESTS are finished and data is fetched.
What's the best way of doing this? Should i use the counter to check that all requests are completed and use completion handler?
Upvotes: 0
Views: 177
Reputation: 981
You can use DispatchGroup
. Use enter()
and leave()
functions to decide when a new task will start and did finish. Then, use notify()
function to do whatever you need to do when the dispatch group is empty (which is decided by counting enter and leave actions).
Upvotes: 1