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.