I'm trying to use some of the new diffing classes built into iOS 13 along with Core Data. The problem I am running into is that controllerdidChangeContentWith doesn't work as expected. It passes me a snapshot reference, which is a reference to a
NSDiffableDataSourceSnapshot<Section, NSManagedObjectID>
meaning I get a list of sections/Object ID's that have changed.
This part works wonderfully. But the problem comes when you get to the diffing in the collection view. In the WWDC video they happily call
dataSource.apply(snapshot, animatingDifferences: true)
and everything works magically, but that is not the case in the actual API.
In my initial attempt, I tried this:
resolvedSnapshot.appendItems(snapshot.itemIdentifiersInSection(withIdentifier: section).map {
controller.managedObjectContext.object(with: $0 as! NSManagedObjectID) as! Activity
}, toSection: .all)
And this works for populating the cells, but if data is changed on a cell (IE. the cell title) the specific cell is never reloaded. I took a look at the snapshot and it appears the issue is simply that I have references to these activity objects, so they are both getting updated simultaneously (Meaning the activity in the old snapshot is equivalent to the one in the new snapshot, so the hashes are equal.)
My current solution is using a struct that contains all my Activity class variables, but that disconnects it from CoreData. So my data source became:
var dataSource: UICollectionViewDiffableDataSource<Section, ActivityStruct>
That way the snapshot actually gets two different values, because it has two different objects to compare. This works, but it seems far from elegant, is this how we were meant to use this? Or is it just in a broken state right now? The WWDC video seems to imply it shouldn't require all this extra boilerplate.