Handling iOS 14 Diffable Data Sources

Diffable data sources get section snapshots and first-class reordering support

Anupam Chugh
Nov 13, 2020 · 6 min read
Crayons
Crayons
Photo by Jess Bailey on Unsplash.

Despite introducing SwiftUI (a declarative UI framework) with iOS 13, Apple still brought in a slew of new changes to the UIKit framework. Among the standout features were the enhancements to UICollectionView.

Specifically, the Compositional Layouts and Diffable Data Sources APIs allowed building advanced CollectionView layouts and centralized data sources a whole lot more easily.

iOS 14 takes it further by bringing a new cell registration API and providing out-of-the-box support for UITableView within UICollectionView.

But more importantly, diffable data sources in iOS 14 now include section snapshots. This means you can now update data on a per-section basis, which is immensely useful in building Outlined Styled lists, the new hierarchical design introduced with iOS 14.

First-class reordering capabilities is the other addition to diffable data sources this year.

Our Goal

  • A quick recap of diffable data sources.
  • Understanding how to implement section snapshots.
  • Digging into the new reordering API.

Recap of Diffable Data Sources

Prior to this new declarative API, developers had to fall back on the numberOfItemsInSection, numberOfSections, cellForItemAt methods for creating the data source. And to update the data, performBatchUpdates() and reloadData() were the go-to methods.

This approach works fine but led to a decentralized data source. Worse yet, the reloadData() method ruined our chances of showing nice animations, while performBatchUpdates would inadvertently lead to common mistakes such as NSInternalInconsistencyException.

With the new diffable data sources, we have a centralized and dedicated data source wherein the data is provided through snapshots.

Snapshots represent a single state of data that doesn’t depend upon index paths for updating items. Instead, it relies on type-safe unique identifiers to identify unique sections and items.

Even better, you could set in the NSDiffableDataSourceSnapshot instance to the UITableView or UICollectionView’s data source using the apply method and let it take care of animations. Interestingly, the apply method can be executed from the background thread as well.

All in all, diffable data sources compute differences and allow for much easier management of data sources in our UICollectionView and UITableView layouts. You can access dataSource.snapshot() to access the current state of UI elements and add/remove items accordingly.

iOS 14 Introduces SectionSnapshots

Prior to iOS 14, to populate items and sections in iOS 13, we had to use the following methods on the NSDiffableDataSourceSnapshot:

And to add items in a section, we’d use the following method:

So, what does the new NSDiffableDataSourceSectionSnapshot API bring to the table considering we could already add items on a per-section basis?

Short answer: customising outlined/expandable lists.

By using the NSDiffableDataSourceSectionSnapshot API, you can easily create and update expandable collection views with the ability to expand and collapse certain sections. This is handy in building hierarchical data.

Here are the methods exposed with the new section snapshots in iOS 14:

Code snippet
Code snippet

Now, let’s create an iOS 14 CollectionView by using the brand new section snapshots for our data sources.

Our data source will hold hierarchical data of strings. So, let’s create two structs of items with a childItems array:

Since both the parent item (the header) and childItems are strings, we need a way to differentiate their types for the distinct UICollectionViewCell they’d go in. Understandably, we’ll create an enum of cases for both of them:

Now that our data model is ready, here’s a sneak peek at our dummy data that’ll be used to populate UICollectionView:

Dummy data
Dummy data
Image by author.

By using the new iOS 14 cell registration techniques, we don’t need to use the traditional cell identifier way of initializing UICollectionViewCell.

Here’s a look at how to create and display contents in the iOS 14 UICollectionView.CellRegistration and pass them to the UICollectionViewDiffableDataSource:

Note that we’ve registered two cells. One acts as the root of each section and contains the disclosure indicator. The other is used to display the contents of each child item.

Now that our data source is ready, it’s time to set it on the CollectionView:

Finally, we’ll apply the snapshot on the data source above.

A section snapshot is constructed in the following way:

We’ve iterated over the hierarchical data and set the parent instance as the header of each section, with the childItems set within it. Also, we’ve expanded each header section to display all items (you can configure this to hide/expand only specific sections as well).

Finally, the section snapshot is applied to the root section of the UICollectionView and the app looks like the following when run on the simulator:

App
App
Screenshot by author.

The full source code of the UICollectionView + diffable data sources and section snapshots is available on GitHub.

You can also customise the expansion states of the various section items by setting the sectionSnapshotHandlers on the dataSource. SectionSnapshotHandler<Item> provides different closures, such as shouldCollapseItem, willCollapseItem, willExpandItem, and shouldExpandItem.

Using the New Reordering API

While section snapshots help to generate expandable lists and determine nested levels of items (the root of the list), there’s also a reordering API that can be quickly plugged onto our diffable data sources.

Specifically, to enable reordering, you need to define the following two closures:

Code snippet
Code snippet

Understandably, for cell registration, you need to set an accessory in the following way:

Note: For brevity’s sake, we set the reordering icon to always be displayed. But it's recommended to set an Edit button that toggles between whenEditing and whenNotEditing states for enabling/disabling reordering.

App
App

The didReorder and willReorder closures pass a new type known as NSDiffableDataSourceTranscation.

The transaction consists of all the relevant information needed to update the diffable data source:

Code for transaction
Code for transaction

CollectionDifference is a new type introduced with Swift 5.1. It describes the insertion and removal of items across two collection states.

So, you can simply update the original data source with the reordered transaction inside the didReorder closure in the following way:

Conclusion

That concludes this article about the changes to iOS 14 diffable data sources. By using section snapshots and the new reordering API, you can easily compose and update chunks of data in your CollectionViews.

Thanks for reading.

Better Programming

Advice for programmers.

Sign up for The Best of Better Programming

By Better Programming

A weekly newsletter sent every Friday with the best articles we published that week. Code tutorials, advice, career opportunities, and more! Take a look

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Thanks to Zack Shapiro

Anupam Chugh

Written by

Pouring thoughts in technology and code. Writer with over 2M views. An Android and iOS developer by the day. Sometimes funny. linktr.ee/anupamchugh

Better Programming

Advice for programmers.

Anupam Chugh

Written by

Pouring thoughts in technology and code. Writer with over 2M views. An Android and iOS developer by the day. Sometimes funny. linktr.ee/anupamchugh

Better Programming

Advice for programmers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store