iOS13 DiffableDataSource Invalid parameter not satisfying: indexPath || ignoreInvalidItems
Asked Answered
H

5

9

I'm converting my collection view to new iOS13 UICollectionViewDiffableDataSource... so I need to update cell information on demand.

Here is my code:

let snap = self.diffDataSouce.snapshot
snap?.reloadItems(withIdentifiers: [itemToUpdate]) //reload cell info
self.diffDataSouce.apply(snap, animatingDifferences: true)

But I get Invalid parameter not satisfying: indexPath || ignoreInvalidItems ...why? My current snap contains itemToUpdate and also my array of models...

I think it's because snap.indexOfItemIdentifier(itemToUpdate) returns not found (NSNotFound)...but that's should be impossible according data model.

Have you some hints?

Honorary answered 25/11, 2019 at 10:36 Comment(0)
A
0

I ran into this problem when I was attempting to reload items that had been deleted from my snapshot. This will get you the same or a similar error. Make sure you data model and snapshot are in sync to avoid this error.

Attalie answered 22/1, 2020 at 7:17 Comment(0)
E
4

Your data model has to conform to Hashable and Equatable, so that the diffing algorithm can track changes between snapshots.

If there is an issue with a collision between two objects, or you have implemented either of those protocols in such a way as to allow for two objects to appear equal to the diffing algorithm, you will get a runtime assert exception.

I'd track down exactly how your model object have inherited or implemented those protocols.

Ewan answered 17/1, 2020 at 15:23 Comment(0)
C
2

Have you implemented the static func == for your model? I had a similar issue using structs where equality is evaluated among all properties

Conan answered 7/12, 2019 at 14:0 Comment(1)
@Honorary could you post your model?Conan
L
2

For my case, reloading a hashable item was the problem. Instead I should have deleted hashable item and inserted anew. Following are the specifics.

My diffable ItemIdentifierType was of AnyHashable type as in:

var dataSource: UICollectionViewDiffableDataSource<AHashableEnum, AnyHashable>!

And whenever I wanted to reload a single item like the author of this exchange, I was experiencing the crash:

var currentSnapshot = dataSource.snapshot()
currentSnapshot.reloadItems([hashableItemThatGotUpdated])
dataSource.apply(currentSnapshot, animatingDifferences: true)

I realized that since ItemIdentifierType is of AnyHashable type, reloading an item is not permitted if its hashvalue has changed. Because the hash value of the new item does not exist in the current snapshot and therefore is not reloadable. Instead I should have deleted the old item from the current snapshot and inserted the new Hashable identifer instead:

var currentSnapshot = dataSource.snapshot()
currentSnapshot.insertItems(identifiers: [NewHashableItemIdentifier], beforeItem: OldHashableItemIdentifier)
currentSnapshot.deleteItems(identifiers: [OldHashableItemIdentifier])
dataSource.apply(currentSnapshot, animatingDifferences: true)
L answered 9/9, 2020 at 20:7 Comment(0)
B
1

In my case I was comparing two instances of different types.

public enum ChatSectionEnum: Hashable {

    case loading
    case messages(String)

    var sectionId: AnyHashable {
        switch self {
        case .loading:
            return UUID() // UUID type
        case .messages(let id):
            return id // String type
        }
    }

    public static func == (lhs: ChatSectionEnum, rhs: ChatSectionEnum) -> Bool {
        lhs.sectionId == rhs.sectionId // Error
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(sectionId)
    }
}
Beaudette answered 30/12, 2022 at 14:52 Comment(0)
A
0

I ran into this problem when I was attempting to reload items that had been deleted from my snapshot. This will get you the same or a similar error. Make sure you data model and snapshot are in sync to avoid this error.

Attalie answered 22/1, 2020 at 7:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.