DiffableDataSource failing to reconfigure cell

I keep getting random crashes, when attempting to reconfigure an existing item. I check immediately for that if the item identifier exists in the data source and do not attempt to configure it if it's not. This is there error message: "Attempted to reconfigure item identifier that does not exist in the snapshot: ..."

Fatal Exception: NSInternalInconsistencyException
0  CoreFoundation                 0x9cb4 __exceptionPreprocess
1  libobjc.A.dylib                0x183d0 objc_exception_throw
2  Foundation                     0x4e154c _userInfoForFileAndLine
3  UIKitCore                      0xa44a8 -[__UIDiffableDataSourceSnapshot _validateReloadUpdateThrowingIfNeeded:]
4  UIKitCore                      0xa2ed8 -[__UIDiffableDataSourceSnapshot _commitUpdateAtomic:]
5  UIKitCore                      0x561048 -[__UIDiffableDataSourceSnapshot reconfigureItemsWithIdentifiers:]
6  libswiftUIKit.dylib            0x35d0c NSDiffableDataSourceSnapshot.deleteItems(_:)
7  Trulia                         0x45380c closure #1 in ActivityFeedV3ViewController.updateUI(for:)
8  Trulia                         0x4c4f58 thunk for @escaping @callee_guaranteed () -> () (<compiler-generated>)

Replies

I'm not sure there's much we can do to help you here, with such limited information.

One thing to think about: I suspect you could get errors like this if your snapshot item's conformance to Identifiable is incorrectly implemented, or if the item identifier's conformance to Equatable or Hashable is incorrectly implemented.

For example, if you have a collection of Widgets, and each Widget has a name (String`), and the name is editable or can change from time to time, then it wouldn't work to use the name as part of the item identifier.

  • The problem only happens occasionally. The Identifiable uses a string that is a constant for each item that cannot change. The hash and == methods are about as simple as they can be. Am still baffled.

Add a Comment

Sorry for the lack of additional details, but boss says I can't post any IP :(

I hear what you are saying regarding what could happen in your Widgets example. We should not be in that situation, but I will triple check with our data folks to make sure the id we are using is not changing. However, if you look at the following snippet you can see that I check to make sure the itemIdentifiers array contains the item immediately before calling reconfigureItems() method. I did verify that we only operate on the items when on the main queue so there should be no threading issues. I also see the same rare crash when I was using the reloadItems() method.

I will continue to scratch my head to see what is going on, but it sounds like you are saying there probably is not a problem with reconfigureItems(). Would that be accurate?

var snapshot = dataSource.snapshot()

if snapshot.itemIdentifiers.contains(leadModel) {
      snapshot.reconfigureItems([leadModel])
      dataSource.apply(snapshot, animatingDifferences: true)
}