Skip to content

Instantly share code, notes, and snippets.

@NeilsUltimateLab
Created February 3, 2019 08:21
Show Gist options
  • Select an option

  • Save NeilsUltimateLab/3bb7ffe0dd2dc86cb765dcea8e2c4c01 to your computer and use it in GitHub Desktop.

Select an option

Save NeilsUltimateLab/3bb7ffe0dd2dc86cb765dcea8e2c4c01 to your computer and use it in GitHub Desktop.
Data Source Manager with pagination.
import Foundation
struct DataSourceManager<A> {
private var _currentPage: UInt = 1
private var _initialPageIndex: UInt = 1
init(intialPageIndex: UInt = 1, dataPerPage: Int = 10) {
self._currentPage = intialPageIndex
self._initialPageIndex = intialPageIndex
self.dataPerPage = dataPerPage
}
var shouldConsiderEachDataAsSection: Bool = false
var dataPerPage: Int = 10
var onDataSourceChange: (([A]) -> Void)?
var dataSource: [A] = [] {
didSet {
onDataSourceChange?(dataSource)
}
}
private var latestDataSource: [A] = [] {
didSet {
guard !self.dataFetchingState.isFetching else { return }
if isFirstPage {
self.dataSource = latestDataSource
}
else {
self.dataSource.append(contentsOf: latestDataSource)
}
}
}
var dataFetchingState: FetchingState<[A]> = .fetching {
didSet {
validateFetchingState()
}
}
private mutating func validateFetchingState() {
switch self.dataFetchingState {
case .fetching, .fetchedError(_):
break
case .fetchedData(let data):
self.latestDataSource = data
}
}
var currentPage: Int {
return Int(self._currentPage)
}
var isFirstPage: Bool {
return self._currentPage == self._initialPageIndex
}
var isLastPage: Bool {
return !canFetchMore
}
var latestDataCount: Int {
return latestDataSource.count
}
var lastIndexPath: IndexPath {
return IndexPath(row: self.dataSource.count - 1, section: 0)
}
mutating func resetPage() {
self._currentPage = self._initialPageIndex
}
mutating func incrementPage() {
self._currentPage += 1
}
mutating func insert(_ item: A, at index: Int) {
self.dataSource.insert(item, at: index)
}
mutating func removeItem(at index: Int) {
self.dataSource.remove(at: index)
}
mutating func removeAll() {
self.dataSource.removeAll()
}
mutating func update(_ item: A, at index: Int) {
if index < self.dataSource.count {
self.dataSource[index] = item
}
}
mutating func append(_ item: A) {
self.dataSource.append(item)
}
var canFetchMore: Bool {
return self.latestDataSource.count/dataPerPage >= 1
}
func canFetchMore(for indexPath: IndexPath) -> Bool {
if shouldConsiderEachDataAsSection {
return lastIndexPath.row == indexPath.section && canFetchMore && (!self.dataFetchingState.isFetching)
}
return lastIndexPath.row == indexPath.row && canFetchMore && (!self.dataFetchingState.isFetching)
}
mutating func removeData(at indexPath: IndexPath) {
self.dataSource.remove(at: indexPath.row)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment