Serial API calls in Swift

Codecat15
4 min readMar 28, 2021
Photo by Meriç Dağlı on Unsplash

Very often we encounter a situation in our project where we want to make multiple API calls serially (one after the other). You will make an API call wait for the response and process the response as per your business use case and then trigger the next API call.

Some may suggest using the Operation queue’s addDependency function or serial queues for this task.

But there’s just one small surprise waiting for you when you go with either of the approaches and the name of the surprise is URLSession.

URLSession carries out its operation in a separate background thread and will cause an illusion of completion to either the Operation queue or serial queue that you are using.

Hence, we must use brute force i.e we need to force wait for an operation till the time URLSession receives a response from the server and the entire response handling is done.

We can use two approaches, one is dispatch semaphore and the other is using dispatch group.

Note: We need to call an API one after the other so there’s dependency here we need to wait for an operation to finish until we kick off the next operation.

Let’s discuss both the approaches one by one

Dispatch semaphore approach:

Semaphore is the most common approach that you will come across the internet, they do a fantastic job in making serial API calls by waiting for an operation to complete using the wait function.

But then I have always preferred to avoid using semaphores if I can.

Semaphores are locks, yes they block the thread and handle race conditions very effectively but then if we are unlucky they do give rise to other issues like deadlocks or priority inversion.

And then to handle those situations we need to write extra code, test cases and ask QA to perform extra testing. I think one must avoid choosing a solution that solves one thing but opens a backdoor for other issues.

Photo by Benjamin Disinger on Unsplash

It’s like driving a car with a bad engine, if you are lucky you will reach the destination and if not then better get that towing van number handy.

Let’s talk about the next approach which is the dispatch group.

Dispatch group approach:

What does the semaphore and dispatch group have in common??? You guessed it right they both have the wait function which you can use to wait for an operation to complete.

However, the wait function of a semaphore works differently as compared to the wait function of a dispatch group. The wait function of the dispatch group will wait synchronously for the previously submitted task to finish.

https://developer.apple.com/documentation/dispatch/dispatchgroup/2016090-wait

So to serially call an APIs here’s pseudocode that we can apply using a combination of operation queue and dispatch group to wait for an operation to fully complete before it triggers the next one

Why operation queue you ask?

I prefer using the highest level of abstraction here and also because the operation queue internally uses GCD but you may also use a serial queue.

Using block operation, if one operation is dependent on the other we can specify those dependencies in the code using the addDependency function thus making our code more readable.

If you want to get your hands on the entire source code, you may click on this link

So basically now we have two approaches that literally do the same thing but one imposes a lock on the shared resource and the other just waits synchronously so which one to choose?

In my opinion, whatever fits your requirement should be your tool for the job, I personally try to avoid a solution that has locks but there can be situations where you want that behavior of locking so do make sure you test your code for all of your business use cases before you release a solution with a lock.

The wait function of dispatch semaphore and group if used on the main thread will freeze your app so make sure you avoid using it on the main thread.

I hope this article was helpful to you, do share your views on what you think about it and your experience on how you have handled serial API calls would love to hear from you.

Thank you for your time in reading the article, have a nice day, and Happy iCoding.

--

--