Skip to content

Instantly share code, notes, and snippets.

@dsxsxsxs
Created March 22, 2021 06:53
Show Gist options
  • Save dsxsxsxs/648680db910ea5871af06c4d64c98b10 to your computer and use it in GitHub Desktop.
Save dsxsxsxs/648680db910ea5871af06c4d64c98b10 to your computer and use it in GitHub Desktop.
infinitePaging.swift
import RxSwift
import RxRelay
protocol IssueListRepositoryProtocol {
func fetch(page: Int) -> Single<[Issue]>
}
final class IssueListUseCase {
private let fetchTrigger = PublishRelay<FetchMode>()
private let issuePagesRelay = BehaviorRelay<[[Issue]]>(value: [])
private let disposeBag = DisposeBag()
let issues: Observable<[Issue]>
init(repository: IssueListRepositoryProtocol) {
fetchTrigger.filter { $0.isRefresh }
.flatMapFirst { _ in repository.fetch(page: 1).map { [$0] } }
.bind(to: issuePagesRelay)
.disposed(by: disposeBag)
fetchTrigger.filter { !$0.isRefresh }
.withLatestFrom(issuePagesRelay) { $1 }
.flatMapFirst { pagesOfIssues in
repository.fetch(page: pagesOfIssues.count + 1)
.map { pagesOfIssues + [$0] }
}
.bind(to: issuePagesRelay)
.disposed(by: disposeBag)
issues = issuePagesRelay.skip(1).map { $0.flatMap { $0 } }
}
func fetch() {
fetchTrigger.accept(.refresh)
}
func next() {
fetchTrigger.accept(.next)
}
}
extension IssueListUseCase {
enum FetchMode {
case refresh
case next
var isRefresh: Bool {
switch self {
case .refresh: return true
case .next: return false
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment