Reputation: 400
I would like to download from firebase:
Then I can instantiate a group object with its data and its image
First approach, I used 3 nested closures that allowed me to get data, and then to get the image.
It did work, but it was quite long to get sequentially all that stuffs from firebase.
So I tried to use GCD in order to push my 2 latest Firebase queries (user data + group image) at the same time (rather than one after the other), and to wait for the last callback to start instantiating my group.
Is it a correct approach ?
If yes, I find some difficulties to implement it... My issue : returnedUser and returnedGroupImage are always nil
Here is my bunch of code :
static func getGroup(_ groupID:String, completionBlock: @escaping (_ group: Group?) -> ()) {
dataRef.child("data").child("groups").child(groupID).observe(.value, with: { (snapshot) in
if let snapshotValue = snapshot.value {
guard let name = (snapshotValue as AnyObject).object(forKey: "name") as? String else
{
completionBlock(nil)
return
}
guard let adminID = (snapshotValue as AnyObject).object(forKey: "adminID") as? String else
{
completionBlock(nil)
return
}
let queue = DispatchQueue(label: "asyncQueue", attributes: .concurrent, target: .main)
let dispatch_group = DispatchGroup()
var returnedUser: User?
var returnedGroupImage: UIImage?
queue.async (group: dispatch_group) {
FireBaseHelper.getUser(adminID, completionBlock: { (user) in
if user != nil {
returnedUser = user
}
})
}
queue.async (group: dispatch_group) {
FireBaseHelper.getGroupImage(groupID, completionBlock: { (image) in
if image != nil {
returnedGroupImage = image
}
})
}
dispatch_group.notify(queue: DispatchQueue.main) {
// Single callback that is supposed to be executed after all tasks are complete.
if (returnedUser == nil) || (returnedGroupImage == nil) {
// always true !
return
}
let returnedGroup = Group(knownID: (snapshotValue as AnyObject).key, named: name, createdByUser: currentUser!)
returnedGroup.groupImage = returnedGroupImage
completionBlock(returnedGroup)
}
}
})
}
Thanks for your help !
Upvotes: 0
Views: 58
Reputation: 5695
I believe that the way you are using DispatchGroup
s are not correct.
let dispatch_group = DispatchGroup()
var returnedUser: User?
var returnedGroupImage: UIImage?
dispatch_group.enter()
FireBaseHelper.getUser(adminID, completionBlock: { (user) in
if user != nil {
returnedUser = user
}
dispatch_group.leave()
})
dispatch_group.enter()
FireBaseHelper.getGroupImage(groupID, completionBlock: { (image) in
if image != nil {
returnedGroupImage = image
}
dispatch_group.leave()
})
dispatch_group.notify(queue: DispatchQueue.main) {
// Single callback that is supposed to be executed after all tasks are complete.
if (returnedUser == nil) || (returnedGroupImage == nil) {
// always true !
return
}
let returnedGroup = Group(knownID: (snapshotValue as AnyObject).key, named: name, createdByUser: currentUser!)
returnedGroup.groupImage = returnedGroupImage
completionBlock(returnedGroup)
}
Upvotes: 1