Created
February 3, 2019 08:21
-
-
Save NeilsUltimateLab/3bb7ffe0dd2dc86cb765dcea8e2c4c01 to your computer and use it in GitHub Desktop.
Data Source Manager with pagination.
This file contains hidden or 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 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