Skip to content

Instantly share code, notes, and snippets.

@erikolsson
Last active January 11, 2024 05:49
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erikolsson/1e18af02d2f22631b875c0e305041d4f to your computer and use it in GitHub Desktop.
Save erikolsson/1e18af02d2f22631b875c0e305041d4f to your computer and use it in GitHub Desktop.
import UIKit
import Combine
protocol DiffableListDataSourceType {
associatedtype SectionIdentifier: Hashable
associatedtype ItemIdentifier: Hashable
func apply(_ snapshot: NSDiffableDataSourceSnapshot<SectionIdentifier, ItemIdentifier>,
animatingDifferences: Bool,
completion: (() -> Void)?)
}
extension UICollectionViewDiffableDataSource: DiffableListDataSourceType {}
extension UITableViewDiffableDataSource: DiffableListDataSourceType {}
extension Subscribers {
fileprivate class Apply<DataSource: DiffableListDataSourceType>: Subscriber, Cancellable {
typealias Failure = Never
private var subscription: Subscription?
private let dataSource: DataSource
private let animatingDifferences: Bool
private let completion: (() -> Void)?
init(dataSource: DataSource, animatingDifferences: Bool, completion: (() -> Void)?) {
self.dataSource = dataSource
self.animatingDifferences = animatingDifferences
self.completion = completion
}
func receive(_ input: NSDiffableDataSourceSnapshot<DataSource.SectionIdentifier, DataSource.ItemIdentifier>) -> Subscribers.Demand {
self.dataSource.apply(input, animatingDifferences: animatingDifferences, completion: completion)
return .none
}
func receive(completion: Subscribers.Completion<Never>) {
}
func receive(subscription: Subscription) {
self.subscription = subscription
subscription.request(.unlimited)
}
func cancel() {
subscription?.cancel()
}
}
}
extension Publisher where Failure == Never {
func apply<DataSource: DiffableListDataSourceType>(to dataSource: DataSource,
animatingDifferences: Bool = true,
completion: (() -> Void)? = nil) ->
AnyCancellable where Output == NSDiffableDataSourceSnapshot<DataSource.SectionIdentifier, DataSource.ItemIdentifier> {
let apply = Subscribers.Apply<DataSource>(dataSource: dataSource,
animatingDifferences: animatingDifferences,
completion: completion)
receive(subscriber: apply)
return AnyCancellable(apply)
}
}
viewModel.sectionSnapshot
.receive(on: DispatchQueue.main)
.apply(to: dataSource)
.store(in: &cancellables)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment