Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use DifferenceKit with diffable data sources? #160

Open
2 tasks done
tinder-cfuller opened this issue May 14, 2024 · 1 comment
Open
2 tasks done

How to use DifferenceKit with diffable data sources? #160

tinder-cfuller opened this issue May 14, 2024 · 1 comment

Comments

@tinder-cfuller
Copy link

tinder-cfuller commented May 14, 2024

Checklist

Detailed Description

How to use DifferenceKit with diffable data sources?

let stagedChangeset = StagedChangeset(source: dataStore.elements, target: newElements)

for changeset in stagedChangeset {

    dataStore.elements = changeset.data

    var snapshot = dataSource.snapshot()

    // What to do here?

    dataSource.apply(snapshot, animatingDifferences: true)
}

While each element can be Identifiable to provide identifiers for the various snapshot methods, it is not clear how to process the changesets.

Please explain in detail how to accomplish this or kindly consider adding methods to the library similar to the existing UIKit/AppKit extensions. Thank you!

@tinder-cfuller
Copy link
Author

The temporary workaround shown below replaces all the identifiers and appears to work, however I am still seeking a solution to apply the deleted/inserted/updated/moved sections and elements for optimum performance.

extension NSDiffableDataSourceSnapshot {

    // MARK: - With Sections

    public mutating func apply<T, U>(
        _ changeset: Changeset<[ArraySection<T, U>]>
    ) where T: Identifiable, T.ID == SectionIdentifierType, U: Identifiable, U.ID == ItemIdentifierType {
        deleteAllItems()
        appendSections(changeset.data.map(\.model).map(\.id))
        for arraySection: ArraySection in changeset.data {
            appendItems(arraySection.elements.map(\.id), toSection: arraySection.model.id)
        }
        reloadSections(changeset.sectionUpdated.map { offset in
            sectionIdentifiers[offset]
        })
        let items: [ItemIdentifierType] = changeset.elementUpdated.map { path in
            itemIdentifiers(inSection: sectionIdentifiers[path.section])[path.element]
        }
        if #available(iOS 15.0, *) {
            reconfigureItems(items)
        } else {
            reloadItems(items)
        }
    }

    // MARK: - Without Sections

    public mutating func apply<T>(
        _ changeset: Changeset<T>
    ) where SectionIdentifierType == Int, T.Element: Identifiable, T.Element.ID == ItemIdentifierType {
        deleteAllItems()
        appendSections([0])
        appendItems(changeset.data.map(\.id))
        let items: [ItemIdentifierType] = changeset.elementUpdated.map { path in
            itemIdentifiers[path.element]
        }
        if #available(iOS 15.0, *) {
            reconfigureItems(items)
        } else {
            reloadItems(items)
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant