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

November 7, 2024

Introducing Shorebird, code push service for Flutter apps

Update Flutter apps without store review What is Shorebird? Shorebird is a service that allows Flutter apps to be updated directly at runtime. Removing the need to build and submit a new app version to Apple Store Connect or Play Console for review for ev...

Christofer Henriksson

Christofer Henriksson

Flutter

May 27, 2024

Introducing UCL Max AltPlay, a turn-by-turn real-time Football simulation

At this year's MonstarHacks, our goal was to elevate the sports experience to the next level with cutting-edge AI and machine learning technologies. With that in mind, we designed a unique solution for football fans that will open up new dimensions for wa...

Rayhan NabiRokon UddinArman Morshed

Rayhan Nabi, Rokon Uddin, Arman Morshed

MonstarHacks

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