Dudi Dudi - 5 months ago 11
iOS Question

Get notification from nested async call with dispatch_group_async

So I have situation when I've want do some async stuff, post status on Facebook and get notified when it's done posting. I was hoping that dispatch_group_async will do the job but now I hit the wall.

Here is how at this moment logic look like.

Func

func saveAndPost() {
//1. save
dispatch_group_async(group, queue) { () -> Void in
print("saving to DB")
//some func
print("saved to DB")
}
//2. post
dispatch_group_async(group, queue, { () -> Void in
print("publishing on FB")
//some func
//async request to ACAccount {
print("access")
//async performRequestWithHandler{
print("posted")
//anwser from request
}
}
}
print("published on FB")
})

dispatch_group_notify(group, queue, { () -> Void in
print("done")
dispatch_async(dispatch_get_main_queue(), { () -> Void in
//go to next view
})
})
}


Output

saving to DB
saved to DB
publishing on FB
published on FB
done
post
posted


My goal is to get notified when whole posting process is done. Maybe this is not possible with dispatch_group_async and I have to use KVO or even PromiseKit?

SOLUTION

David got me thinking and
dispatch_group_enter
& 'dispatch_group_leave' right what I needed. So at this moment my logic look like this.

func saveAndPost() {
//1. save
dispatch_group_async(group, queue) { () -> Void in
print("saving to DB")
//some func
print("saved to DB")
}
//2. post
dispatch_group_enter(group)
print("publishing on FB")
//some func
//async request to ACAccount {
print("access")
//async performRequestWithHandler{
print("posted")
//anwser from request
dispatch_group_leave(group)
}
}
}
print("published on FB")

dispatch_group_notify(group, queue, { () -> Void in
print("done")
dispatch_async(dispatch_get_main_queue(), { () -> Void in
//go to next view
})
})
}


As you can see part 2. is now modified.

Answer

My preferred method to tackle this when dealing with async calls:

var asyncGroup = dispatch_group_create()

dispatch_group_enter(asyncGroup)
asyncCall1.start() {


  //end of callback
  dispatch_group_leave(asyncGroup)
}

dispatch_group_enter(asyncGroup)
asyncCall2.start() {

    asyncCall3.start() {

        asyncCall4.start() {

            dispatch_group_leave(asyncGroup)
        }

    }
}

dispatch_group_notify(asyncGroup, dispatch_get_main_queue(), {
    println("done")
})

asyncCall1.start() { ... } and asyncCall2.start() { ... } are just sorta psuedocode to show you how it works.

Every dispatch_group_enter call needs to be balanced by a dispatch_group_leave call or you'll never get into the dispatch_group_notify block.

Comments