RxSwift處理分頁(yè)數(shù)據(jù)請(qǐng)求

Based on the examples provided with in the RxSwift GitHub repo I managed to do it.
Basically, I'm using a recursive function that returns my stream of PaginatedList items, it calls itself with the loadNextPage trigger for the next page. Here the code I used in my API manager:

class func films(withTitle title: String, startingAtPage page: Int = 0, loadNextPageTrigger trigger: Observable<Void> = Observable.empty()) -> Observable<[Film]> {
    let parameters: FilmSearchParameters = FilmSearchParameters(query: title, atPage: page)
    return TMDbAPI.instance.films(fromList: [], with: parameters, loadNextPageTrigger: trigger)
}

fileprivate func films(fromList currentList: [Film], with parameters: FilmSearchParameters, loadNextPageTrigger trigger: Observable<Void>) -> Observable<[Film]> {

    return self.films(with: parameters).flatMap { (paginatedList) -> Observable<[Film]> in
        let newList = currentList + paginatedList.results
        if let _ = paginatedList.nextPage {
            return [
                Observable.just(newList),
                Observable.never().takeUntil(trigger),
                self.films(fromList: newList, with: parameters.nextPage, loadNextPageTrigger: trigger)
            ].concat()
        } else { return Observable.just(newList) }
    }
}

fileprivate func films(with parameters: FilmSearchParameters) -> Observable<PaginatedList<Film>> {
    guard !parameters.query.isEmpty else { return Observable.just(PaginatedList.Empty()) }
    return Observable<PaginatedList<Film>>.create { (observer) -> Disposable in
        let request = Alamofire
            .request(Router.searchFilms(parameters: parameters))
            .validate()
            .responsePaginatedFilms(queue: nil, completionHandler: { (response) in
                switch response.result {
                case .success(let paginatedList):
                    observer.onNext(paginatedList)
                    observer.onCompleted()
                case .failure(let error):
                    observer.onError(error)
                }
            })
        return Disposables.create { request.cancel() }
    }
}

In ViewModel

fileprivate func setupFilms() -> Observable<[Film]> {

    let trigger = self.nextPageTrigger.asObservable().debounce(0.2, scheduler: MainScheduler.instance)

    return self.textSearchTrigger
        .asObservable()
        .debounce(0.3, scheduler: MainScheduler.instance)
        .distinctUntilChanged()
        .flatMapLatest { (query) -> Observable<[Film]> in
            return TMDbAPI.films(withTitle: query, loadNextPageTrigger: trigger)
        }
        .shareReplay(1)
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容