OperationQueue: Asynchronous Data Provider for list view
By: Mohammed Rokon Uddin
Tags: Objective C, Uitableview, Concurrency, iOS, Swift

In iOS TableView Prefetching DataSource using Swift I talked about prefetching API introduced in iOS 10. To achieve seamless user experience, prefetching API does an excellent job. But at times we need more than prefetching datasource. And 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 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 end results 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 meta data for each image from the internet. Here we used NetworkSimulator to mimic the delay due to network call.

ImageDecompressionOperation:

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

TiltShiftOperation:

The responsibility of this class is to apply gradient with 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 these 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 image available an indexPath or else a new imageProvider has been created and update the cell as soon as image has been return from completion block and finally imageProvider has been stored to 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 to multiple classes. As OperationQueue class is key-value coding (KVC) and key-value observing (KVO) compliant, it keeps track of progress and dependencies of each task. The below code repo is a perfect example of how leverage the power of OperationQueue and design a 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