美文网首页
RxSwift处理分页数据请求

RxSwift处理分页数据请求

作者: TsangHou | 来源:发表于2018-04-03 11:46 被阅读0次

    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)
    }
    

    相关文章

      网友评论

          本文标题:RxSwift处理分页数据请求

          本文链接:https://www.haomeiwen.com/subject/sjuqhftx.html