在做一些 RxSwift 练习时,我一直在玩 PokeApi。Pokeapi 可以在这里找到
我正在使用的 api 示例
在搜索口袋妖怪时,您可以设置要返回的数量的限制,然后在响应中,有一个下一个和上一个参数,这样您就可以继续前进和通过口袋妖怪的背景。部分响应示例
https://pokeapi.co/api/v2/pokemon/?limit=20
{"count":964,"next":" 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
}
这是视图模型的一部分,显示了我在 atm 做的事情
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响应进行分页,但是这里没有页码,都是基于之前的请求响应。
任何帮助将非常感激