iOS реализует нумерацию страниц с помощью ReactorKit и RxSwift - PullRequest
0 голосов
/ 26 сентября 2018

Я работаю над проектом iOS, требующим разбиения на страницы (вызов API будет иметь параметр page для получения результатов).В идеале, когда пользователь прокручивает в нижней части collectionView, вызов API будет вызывать больше результатов (увеличение page число), а затем добавлять новый результат в существующий массив модели.

Вот мойреализация, которая работает, когда пользовательский поиск:

Это PhotoListViewReactor

import RxSwift
import RxCocoa
import ReactorKit

class PhotoListViewReactor : Reactor {

  enum Action {
    case searchFlickr(_ keyword: String, _ page: Int)
  }

  enum Mutation {
    case flickrList([Photos])
  }

  struct State{
    var keyword : String?
    var photos : [Photos] = []
    var page: Int = 1
  }

  var initialState: State = State()

  init() { }

  func mutate(action: Action) -> Observable<Mutation> {
    switch action {
    case let .searchFlickr(keyword,page):
      return AppService.request(keyword: keyword,page: page)
              .catchErrorJustReturn([])
              .map{[Photos(photos: $0)]}
              .map {Mutation.flickrList($0)}
    }
  }

  func reduce(state: State, mutation: Mutation) -> State {
    var newState = state
    switch mutation {
        case let .flickrList(photos):
            newState.photos += photos
            newState.page += 1
    }


    return newState
  }

}

Функция для получения данных из API:

static func request(keyword: String, page: Int) -> Observable<[Photo]>

Я добавил страницу: Int до State struct, но не знаю, как реализовать page (увеличить страницу и вызвать API, когда пользователь прокручивает внизу)

1 Ответ

0 голосов
/ 26 сентября 2018

Вот решение, которое я написал с помощью RxSwift.Суть приходит как с кодом, так и с модульными тестамиhttps://gist.github.com/danielt1263/10bc5eb821c752ad45f281c6f4e3034b

Это обрабатывает следующее:

protocol PaginationUISource {
    var reloadLastPage: Observable<Void> { get } /// reload most recently loaded page
    var loadNextPage: Observable<Void> { get } /// load next page
    var bag: DisposeBag { get }
}

protocol PaginationNetworkSource {
    associatedtype Item
    func loadData(page: Int) -> Observable<[Item]>
}

struct PaginationSink<T> {
    let isLoading: Observable<Bool> /// true if network loading is in progress.
    let elements: Observable<[T]> /// elements from all loaded pages
    let error: Observable<Error> /// fires once for each error
}

Я написал это некоторое время назад, и я думаю, что я мог бы сделать лучше сейчас, но это должно помочь вам начать.

...