Home What is DispatchGroup and how to use it
Post
Cancel

What is DispatchGroup and how to use it

DispatchGroup

All of us ran into case where you need to wait for multiple works to finish to do something, maybe downloading models from multiple APIs then group them, or do a group of API calls and wait them to finish to show success message. How can we do this in a proper way without a lot of flags?

Let’s create a case that we need to enhance: Imagin that when the app starts we need to fetch 3 things in the splash screen before we send the user to the next screen:

  • Configurations
  • Resources
  • Labels.

Without DispatchGroup maybe you will do something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
var configApiDone = false
var resourcesApiDone = false
var labelsApiDone = false
var complition: () -> Void
 
func getAllData() {
  getConfigurations() {
    configApiDone = true
    checkIfFinished()
  }
 
  getResources() {
    resourcesApiDone = true
    checkIfFinished()
  }
 
  getLabels() {
    labelsApiDone = true
    checkIfFinished()
  }
}
 
func checkIfFinished() {
  if configApiDone && resourcesApiDone && labelsApiDone {
    complition()
  }
}

DispatchGroup

DispatchGroup allow us to monitor a group of tasks as a single unit. We add tasks to a group by calling enter() when the task start and leave() when the task end, this calls should be balanced, so if you call enter() 3 times, you should call leave() also 3 times, and when this done the group completion handler will be called.

Using DispatchGroup to enhance the previous code we will have the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 
var complition: () -> Void
 
func getAllData() {
  let dispatchGroup = DispatchGroup();
 
  dispatchGroup.enter()
  getConfigurations() {
    dispatchGroup.leave()
  }
       
  dispatchGroup.enter()
  getResources() {
    dispatchGroup.leave()
  }
       
  dispatchGroup.enter()
  getLabels() {
    dispatchGroup.leave()
  }
       
  dispatchGroup.notify(queue: .main) {
    complition()
  }
}

As you can see, it’s much cleaner and easy to read and there are no more flags or if statements!

One last note, when you use DispatchGroup always remmber to call leave() for every single enter() call, else, the completion handler will not be called!

-❤️~.

To read more about queues you can check the other articles published in this blog under concurrency category.

If you have any questions you can send me a message on Twitter or facebook. Also you can check my Github page or my Apps.

This post is licensed under CC BY 4.0 by the author.