Skip to content

Instantly share code, notes, and snippets.

@lightsprint09
Created October 23, 2017 11:26
Show Gist options
  • Save lightsprint09/cd759ff07b1e174e207ae700b038105a to your computer and use it in GitHub Desktop.
Save lightsprint09/cd759ff07b1e174e207ae700b038105a to your computer and use it in GitHub Desktop.
A DataProvider which can be used by different dataSources at the same time
final public class NameDifferentDataProvider<Element>: DataProviding {
/// Closure which gets called, when a data inside the provider changes and those changes should be propagated to the datasource.
/// **Warning:** Only set this when you are updating the datasource.
public var whenDataProviderChanged: ProcessUpdatesCallback<Element>? {
get {
return realWhenDataProviderChanged
}
set {
newValue.map { didChanges.append($0) }
}
}
private var didChanges: [ProcessUpdatesCallback<Element>] = []
private var realWhenDataProviderChanged: ProcessUpdatesCallback<Element>?
private let objectAtIndexPath: (_ atIndexPath: IndexPath) -> Element
private let numberOfItems: (_ inSextion: Int) -> Int
private let numberOfSectionsCallback: () -> Int
private let prefetchItemsAtIndexPaths: ([IndexPath]) -> Void
private let cancelPrefetchingForItemsAtIndexPaths: ([IndexPath]) -> Void
private let getSectionIndexTitles: () -> [String]?
private let getHeaderTitles: () -> [String]?
public var sectionIndexTitles: [String]? {
return getSectionIndexTitles()
}
public var headerTitles: [String]? {
return getHeaderTitles()
}
public init<DataProvider: DataProviding>(_ dataProvider: DataProvider) where Element == DataProvider.Element {
objectAtIndexPath = { indexPath in
return dataProvider.object(at: indexPath)
}
numberOfItems = { section in
return dataProvider.numberOfItems(inSection: section)
}
numberOfSectionsCallback = {
return dataProvider.numberOfSections()
}
prefetchItemsAtIndexPaths = { indexPaths in
dataProvider.prefetchItems(at: indexPaths)
}
cancelPrefetchingForItemsAtIndexPaths = { indexPaths in
dataProvider.cancelPrefetchingForItems(at: indexPaths)
}
getSectionIndexTitles = {
return dataProvider.sectionIndexTitles
}
getHeaderTitles = {
return dataProvider.headerTitles
}
realWhenDataProviderChanged = { [weak self] updates in
guard let strongSelf = self else { return }
for handler in strongSelf.didChanges {
handler(updates)
}
}
dataProvider.whenDataProviderChanged = realWhenDataProviderChanged
}
public func object(at indexPath: IndexPath) -> Element {
return objectAtIndexPath(indexPath)
}
public func numberOfItems(inSection section: Int) -> Int {
return numberOfItems(section)
}
public func numberOfSections() -> Int {
return numberOfSectionsCallback()
}
public func prefetchItems(at indexPaths: [IndexPath]) {
prefetchItemsAtIndexPaths(indexPaths)
}
public func cancelPrefetchingForItems(at indexPaths: [IndexPath]) {
cancelPrefetchingForItemsAtIndexPaths(indexPaths)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment