Color Mode


    Language

UITableView DataSource Prefetching

January 14, 2022

Apple has introduced an API for prefetching the data for a UITableView or UICollectionView in iOS 10. This is a short story about how to implement the UITableViewDataSourcePrefetching protocol. Let's learn how to make our apps buttery smooth, richer, and faster by using new features in UITableView and its sibling, UICollectionView.

Overview

To implement prefetching, we conform to the UITableViewDataSourcePrefetching protocol in our ViewController, just like UITableViewDataSource and UITableViewDelegate. That enables UITableView’s data source to begin loading data for cells before tableView(_:cellForRowAt:) data source method is called.

Getting Started

Set your ViewController to TableView prefetch datasource

tableView.prefetchDataSource = self

Initiate asynchronous loading of the data required for the cells at the specified index paths in your implementation of tableView(_:prefetchRowsAt:)

func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
	for indexPath in indexPaths {
		if let _ = loadingOperations[indexPath] { return }
		if let dataLoader = dataStore.loadImage(at: indexPath.row) {
			loadingQueue.addOperation(dataLoader)
			loadingOperations[indexPath] = dataLoader
		}
	}
}

Cancel pending data load operations when the TableView informs you that the data is no longer required in the tableView(_:cancelPrefetchingForRowsAt:) method

func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) {
	for indexPath in indexPaths {
		if let dataLoader = loadingOperations[indexPath] {
			dataLoader.cancel()
			loadingOperations.removeValue(forKey: indexPath)
		}
	}
}

Loading Data Asynchronously

Unlike tableView(_:cellForRowAt:), the tableView(_:prefetchRowsAt:) method is not necessarily called for every cell in the TableView. It is called for cells that are not visible on the screen. Implementation of tableView(_:cellForRowAt:), therefore, must be able to handle the following potential situations

  • Data has been loaded via the prefetch request and is ready to be displayed.
...  
// Has the data already been loaded?  
if let image = dataLoader.image {
	cell.updateAppearanceFor(image)
	loadingOperations.removeValue(forKey: indexPath)  
}  
...
  • Data is currently being prefetched but is not yet available.
...  
else {
	// No data loaded yet, so add the completion closure to update the cell once the data arrives
	dataLoader.loadingCompleteHandler = updateCellClosure  
}  
...
  • Data has not yet been requested.
...
// Need to create a data loaded for this index path  
if let dataLoader = dataStore.loadImage(at: indexPath.row) {
	// Provide the completion closure, and kick off the loading operation
	dataLoader.loadingCompleteHandler = updateCellClosure
	loadingQueue.addOperation(dataLoader)
	loadingOperations\[indexPath\] = dataLoader  
}
...

To handle all of these situations Operation is used to load the data for each row. We create the Operation object and store it in the prefetch method. The data source method can then either retrieve the operation and result or create a new operation if doesn’t exist.

class DataLoadOperation: Operation {
	var image: UIImage?
	var loadingCompleteHandler: ((UIImage?) -> ())?
	private let imageModel: ImageModel

	init(_ imageModel: ImageModel) {
		self.imageModel = imageModel
	}

	override func main() {
		if isCancelled { return }
		guard let url = imageModel.url else { return }
		downloadImageFrom(url) { (image) in
			DispatchQueue.main.async() { [weak self] in
				guard let `self` = self else { return }
				if self.isCancelled { return }
				self.image = image
				self.loadingCompleteHandler?(self.image)
			}
		}
	}
}
Seamless Prefetching...!!!

Conclusion

I hope this blog helped you understand how to implement the prefetching protocol. I tried to be very brief and focused. If you want to know more about it, I encourage you to watch Apple’s WWDC session on the prefetching protocol.

👑 KEEP CALM AND HERE IS MY CODE

iosswiftuitableviewuicollectionviewdatasource

Author

Rokon Uddin

Rokon Uddin

Senior Mobile Engineer Ⅱ

iOS Developer📱| Tech Enthusiast | Tea Lover ☕️ | Occasional Chef 👨‍🍳 | Soccer Player ⚽️

You may also like

May 26, 2023

Exploring Traefik: A simpler and faster web server

In this article, I will introduce a powerful web server named Traefik, written in the Go language. Compared with Nginx, currently the most popular web proxy server, Traefik stands out for its simplicity and speed. Here are the official website and source ...

Meng Li

Meng Li

May 25, 2023

Build your first smart contract with Ethereum and Solidity

Smart contracts are an exciting way to build decentralized applications (DApps) on a blockchain. This tutorial will guide you in building your first smart contract on the Ethereum blockchain using Solidity. What is a Smart Contract? According to Wikipedia...

Cuong Le

Cuong Le

ServicesCasesAbout Us
CareersThought LeadershipContact
© 2022 Monstarlab
Information Security PolicyPrivacy PolicyTerms of Service