OperationQueue: Asynchronous Data Provider for list view

Mohammed Rokon Uddin
Monstar Lab Bangladesh Engineering
3 min readJan 28, 2020

--

In iOS TableView Prefetching DataSource using Swift, I talked about the prefetching API introduced in iOS 10. To achieve a seamless user experience, prefetching API does an excellent job. But at times we need more than prefetching datasource. One of those times is when the data we want to fetch are from multiple synchronous slow-running tasks depending on one another. Considering such cases, in this article, I explained how to group multiple heavy tasks (both sync and async) using Swift’s powerful multithreading API Operation and I called it an Asynchronous Data Provider.

Prerequisite

As you are reading this article, I am hoping that you already know about GrandCentralDispatch (GCD), OpertionQueue and PrefetchingDataSource .

Getting Started

The sample project of this article populates a table view of filtered images. These images are the results of four heavy loading tasks, both synchronous and asynchronous. I made each task as a subclass of Operation to run these tasks in a OperationGroup and assign one as a dependency of another task.

DataLoadOperation:

This is the first of four tasks used to fetch images. It downloads the metadata for each image from the internet. Here we used NetworkSimulator to mimic the delay due to network call.

ImageDecompressionOperation:

As the name says, this decompresses the compressed data downloaded in DataLoadOperation to UIImage

TiltShiftOperation:

The responsibility of this class is to apply a gradient with a corner radius to the UIImage passed from ImageDecompressionOperation

ImageFilterOutputOperation:

This calls the completion block to return the final output.

TiltShiftImageProvider:

This is where all the magic happens. TiltShiftImageProvider. It initializes all tasks, assigns the dependencies to one other accordingly, and in the end adds this array of tasks to OperationQueue. TiltShiftImageProvider just has a single method cancel() which is called whenever we want OperationQueue to stop any ongoing task.

TiltShiftTableViewController:

Inside tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) a new imageProvider is initialized and stored in a dictionary. tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) method calls configureCell(_ cell: ImageTableViewCell, at indexPath: IndexPath) to update UI If there is an image available an indexPath or else a new imageProvider has been created and update the cell as soon as the image has been returned from the completion block and finally imageProvider has been stored in the dictionary. In tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) and tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) methods we called cancel() method of each stored imageProvider to stop any ongoing task and then imageProvider has been removed from the dictionary to free up the resources.

Conclusion

Operations in Swift are a very powerful way to segregate tasks into multiple classes. As OperationQueue the class is key-value coding (KVC) and key-value observing (KVO) compliant, it keeps track of the progress and dependencies of each task. The below code repo is a perfect example of how to leverage the power of OperationQueue and design an Asynchronous Data Provider.

Thank you all for your attention 🙏🏻. feel free to tweet and get connected.

Check out other articles from our engineering team:
https://medium.com/monstar-lab-bangladesh-engineering

Visit our website to learn more about us:
www.monstar-lab.co.bd

--

--

Mohammed Rokon Uddin
Monstar Lab Bangladesh Engineering

[ Apple Platform Developer | Tea & Coffee Brewer ☕️ | Occasional Chef 👨‍🍳 | Soccer Player ⚽️ ]