Combining DispatchGroup and DispatchQueue

1.4k views Asked by At

My scenario is like this. I need to send a Network Request, in response i will become a list of Image URLs. I would then need to send multiple network requests concurrently to get all of these Images and once i have all the Images downloaded , I need to populate a tableView.

To fulfil these requirements i am trying to understand the relationship between DispatchQueue and DispatchGroup in Playground and so far this is my code.

var concurrentQueue = DispatchQueue(label: "test",attributes: .concurrent)
var myGroup = DispatchGroup()
var mySecondGroup = DispatchGroup()

myGroup.notify(queue: DispatchQueue.main) {
    print("Initial Json request with List of URLs completed")
    mySecondGroup.enter()
    concurrentQueue.async {
        for i in 10...15 {
            print(i)
            if(i==15){
                mySecondGroup.leave()
            }
        }
    }
}

mySecondGroup.notify(queue: DispatchQueue.main) {
    print("All Images download complete")
}

myGroup.enter()
concurrentQueue.async {
    for i in 0...5 {
        print(i)
        if(i==5){
            myGroup.leave()
        }
    }
    
}

The problem is i am getting the result

0
1
2
3
4
5
Initial Json request with List of URLs completed
10
11
All Images download complete
12
13
14
15

But what i want is something like this

0
1
2
3
4
5
Initial Json request with List of URLs completed
10
11
12
13
14
15
All Images download complete

I am not really understanding what i am doing wrong here and any help would be greatly appreciated.

1

There are 1 answers

0
vadian On

DispatchQueue is the medium where the tasks are scheduled on.

DispatchGroup works like a counter. Calling enter increments the counter (usually before calling the asynchronous task) and leave decrements the counter (usually inside the completion handler). When the counter reaches zero the group notifies.

Your scenario needs something like this

let concurrentQueue = DispatchQueue(label: "test",attributes: .concurrent)
let group = DispatchGroup()
concurrentQueue.async {
    asynchronousAPI.call() { urls in
        for url in urls {
            group.enter()
            asynchronousImageLoad(url) { data in
               // process data
               group.leave()
            }
        }
    }
}
group.notify(queue: .main) {
    print("done")
}