Reputation: 61
I'm trying to create a UISearchController to find friends on my app. To populate the array which the search controller is filtering, I'm getting my users' document IDs from Firestore. This uses an asynchronous method getDocuments. I'm trying to use a dispatch group so that my code still runs in the desired order, but it's not working. Here is my function:
func setAllUsers(completion: @escaping ([User]) -> Void) {
let dispatchGroup = DispatchGroup()
var temp = [String]()
dispatchGroup.enter()
FirestoreService.db.collection(Constants.Firestore.Collections.users).getDocuments { (snapshot, err) in
if let err = err {
print("Error accessing user collection: \(err)")
} else {
var counter = 0
for doc in snapshot!.documents {
counter += 1
print("Counter: \(counter)")
temp.append(doc.documentID)
}
}
dispatchGroup.leave()
}
dispatchGroup.notify(queue: .main) {
completion(UserService.getUserArray(uids: temp))
}
}
Here is the call in viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
setAllUsers { (users) in
self.allUsers = users
}
print("Number of users in Firestore: \(allUsers.count)")
}
When I run the code, I see this in the console: Number of users in Firestore: 0 Counter: 1 Counter: 2 Counter: 3
How do I fix the order here?
Upvotes: 0
Views: 73
Reputation: 285069
How do I fix the order here?
Very easy, put the line into the closure, it contains the asynchronous code.
setAllUsers { (users) in
self.allUsers = users
print("Number of users in Firestore: \(self.allUsers.count)")
}
And you are misusing DispatchGroup
, it's not needed
func setAllUsers(completion: @escaping ([User]) -> Void) {
var temp = [String]()
FirestoreService.db.collection(Constants.Firestore.Collections.users).getDocuments { (snapshot, err) in
if let err = err {
print("Error accessing user collection: \(err)")
} else {
var counter = 0
for doc in snapshot!.documents {
counter += 1
print("Counter: \(counter)")
temp.append(doc.documentID)
}
completion(UserService.getUserArray(uids: temp))
}
}
}
Upvotes: 1
Reputation: 16341
You need to call it inside the closure. Also, you don't need the DispatchGroup
.
override func viewDidLoad() {
super.viewDidLoad()
setAllUsers { (users) in
self.allUsers = users
print("Number of users in Firestore: \(allUsers.count)")
self.tableView.reloadData() // reload the view you're trying to populate with users here.
}
}
Upvotes: 0