Я играл с PokeApi, занимаясь практикой RxSwift. Pokeapi можно найти здесь
https://pokeapi.co/
Пример API, с которым я работаю
При поиске в pokemon вы можете установить предел того, сколько вы хотите вернуть, затем в ответе есть следующий и предыдущий параметры, чтобы вы могли продолжать идти вперед и проходить через покемона. Пример части ответа
https://pokeapi.co/api/v2/pokemon/?limit=20
{ "счетчик": 964, "рядом": "https://pokeapi.co/api/v2/pokemon/?offset=20&limit=20","previous":null,"results":....
В моем контроллере есть текстовое поле, где они могут ввести, сколько покемонов они хотят вернуть на страницу, а затем, когда они нажимают на поиск, результаты возвращаются в таблицу, и они могут нажимать следующий и предыдущий для циклического перемещения по страницам. Моя модель выглядит так
struct PokemonSearchData: Codable {
let next: String?
let previous: String?
let results: [PokemonResultsData]
}
struct PokemonResultsData: Codable {
let name: String
let url: String
}
Вот часть модели представления, показывающая, что я делаю в банкомате
extension PokeListViewModel: ViewModelType {
struct Input {
let limitText: Observable<String>
let startRequest: PublishSubject<Void>
let nextTap: Observable<Void>
let previousTap: Observable<Void>
let selectedPokemon: Observable<PokemonResultsData>
}
struct Output {
let responseData: Observable<PokemonSearchData>
let errors: Driver<Error>
}
func transform(input: PokeListViewModel.Input) -> PokeListViewModel.Output {
let request = input.startRequest
.withLatestFrom(input.limitText)
.flatMap { text in
self.service.fetchPokemon(limit: text).materialize()
}.share()
let searchResponse = request.map{$0.element}.filterNil()
let searchError = request.map{$0.error}.asDriver(onErrorJustReturn: RxError.unknown).filterNil()
let nextURL = searchResponse.map{$0.next}.filterNil()
// handle next request and errors
let nextRequest = input.nextTap.withLatestFrom(nextURL).flatMap { nextURL in
self.service.cyclePokemon(stringURL: nextURL).materialize()
}.share()
let nextResponse = nextRequest.map{$0.element}.filterNil()
let nextError = nextRequest.map{$0.error}.asDriver(onErrorJustReturn: RxError.unknown).filterNil()
let mergedResponses = Observable.merge(searchResponse, nextResponse)
let mergedErrors = Driver.merge(searchError, nextError)
// do the same thing for previous response, just cut it out here so less code to paste, but the logic is the same
return Output(responseData: mergedResponses,
errors: mergedErrors)
}
Следующий запрос зависит от первоначального запроса, поэтому, когда я нажимаю следующий раз, он все еще основан на первоначальном запросе, поэтому он просто продолжает возвращать те же данные. Я видел другие примеры кода, делающие нумерацию страниц на основе ответа API, имеющего номера страниц, но здесь нет номера страницы, все это основано на предыдущем ответе на запрос.
Любая помощь будет высоко ценится