Last active
January 11, 2024 05:49
-
-
Save erikolsson/1e18af02d2f22631b875c0e305041d4f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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