Diffable data source for TableView error on iOS 13: Inconsistent associations for moves

Updated Answer

I was fortunate enough to get a response to the bug I raised regarding this. It turns out that my model object was had incorrect Hashing and Equality checks.

My swift structs conformed to Hashable, but provided a custom implementation of Equatable, whereby I only compared the ID property to determine equality. This meant that it was possible for two objects to be considered equal, but have differing hashes, which confuses the diffing algorithm.

To solve it, I simply removed my custom implementation of Equatable, and used the synthesised version.

You state in your question that you implement isEqual, the ObjC, analog to Swift's ==, but you're probably not providing a hash implementation that agrees with your isEqual implementation in all cases.


Original Answer (Possibly incorrect for this case, but may still useful if queues are the problem)

I don't know if this is the same problem you're having, but in my case it was caused by the applySnapshot method being called from different queues.

The Advanced Data Sources WWDC session mentioned that applySnapshot must be exclusively called on a background queue OR the main queue, but don't call from both. Advanced Data Sources WWDC 2019 - 32:00

Advanced Data Sources WWDC 2019

In my case I'm using a Combine publisher to react to changes on my data source, and that publisher was sometimes sending values on the main thread or a background thread. To solve my issue I added .receive(on: RunLoop.Main) to the chain.

In your case, maybe you can wrap anything that makes a call to updateTableViewAnimated: in a dispatch_async call using the queue you want it to run on (be that main or background).


Adding to Jasarien informative answer, you need to keep in mind that UICollectionViewDiffableDataSource use hashable to differentiate between items in your datasource

if your model is a struct, and there're two items in your datasource model which happens to have the exact same values, Hashable protocol will produce the same hashValue for them.

also Equatable protocol will return true! , which will confuse UICollectionViewDiffableDataSource

Solutions

  • Make sure that your Datasource Doesn't have any duplicates
  • if you can't avoid Duplicates, and you don't mind braking Equatable, you might want to add random Value in your datasource, but it's not recommended since the values generated might be equal at any coincidence, as stated in Documentions *low probability, but it might happen *

Depending on the size and span of range, some concrete values may be represented more frequently than others.