A unicorn's head exploding with ideas - blown mind

In this article, we'll discuss iOS 13 Diffable Data Sources and their usage. Prior to iOS 12, we had to conform to the UITableViewDataSource or UICollectionViewDataSource protocol and set its delegate to handle the data source for table view or collection view. Although this approach is well-known, it has had quirks and issues from the beginning that could be frustrating.

iOS Data Handling Evolution

Whenever an application receives some data, its responsibility is to update the view layer with the freshest and most crisp information. This is not always easy to do. The simplest way to reload all the data in the controller was just calling the .reloadData() method on our table or collection view.

This caused two problems: firstly, were using much more computational power than we should and secondly (and more importantly), we lost out on some nice animations. Apple recognised this problem and at last year’s presentation they taught us how to use insertions and removals while working with collection view.

This approach was very error prone. Why? Because it let view and model data to be different and it forces us — developers to handle all of the insertions and deletions. As you might have experienced — it was no easy task.

The lack of one universal source of truth was the reason Apple decided to give for this nice refactor.

Diffable Data Source - the introduction

This is not a new idea in the iOS world. A considerable number of third party frameworks have already aimed to tackle this problem —e.g. Deep Diff or Diff.swift . I remember Vijaya P. Kandel giving a great talk at MobiConf 2018 about this problem. I also remember having a headache, when trying to wrap my head around its underlying algorithm.

What does diffable data source actually do? 

Diffable data source automatically calculates the difference between the old and new data source. Then it is able to apply the changes with a state of the art animation.

So basically instead of old insertions, deletions and performBatchUpdates() :

  

The old error prone method

All we have to do is .apply(snapshot) every time that data is changed.

  

The new, safer method

  1. Create snapshot specifying section and data type
  2. Configure snapshot, by adding needed sections and items
  3. Apply the snapshot to the data source

And that is all we need, so we can forget about:

Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘Invalid update: invalid number of items in section 0. The number of items contained in an existing section after the update (213) must be equal to the number of items contained in that section before the update (154), plus or minus the number of items inserted or deleted from that section (40 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).’

How can I use diffable data source in my project? 

Data source 

In order to use diffable data source, you first need to create it. When it comes to iOS it will be called either UITableViewDiffableDataSource or UICollectionViewDiffableDataSource. In order to do that, you need to specify the section, data type and put a reference to the collection view. What you get inside the body of the function is the same reference to collection view, index path of the cell and the data object, so you could specify the binding behaviour. That’s all the setup needed for the data source.

  

Data object 

Data object used the data source must conform to Hashable protocol. You can read more about it in the documentation, but the most important thing for the data source is that the item has to have a unique hash value. All you need is adding Hashable protocol conformance and compiler will generate the implementation for you.

  

Conclusions 

I hope that I have helped you understand how to implement a diffable data source into your app. After a change to the data, a snapshot with the difference is applied to data source and bang! Everything works well with cool animations and there are no more nasty crashes. It’s just that easy.

If you have any questions, please don’t hesitate to ask me in the comments!