在进行一些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)
}
下一个请求取决于初始请求,因此当我再次按下next时,它仍然基于初始请求,因此它只会返回相同的数据。我已经看到其他代码示例基于具有页面编号的api响应进行分页,但是这里没有页面编号,这全部基于先前的请求响应。
任何帮助将不胜感激
答案 0 :(得分:1)
有一个RXPager吊舱将为您完成此操作。即使您想拥有分页逻辑,查看代码也很有用。基本上,您需要为寻呼机提供2个功能:
1)一种从当前页面生成下一页的方法(如果为第一页,则为nil) 2)具有下一个功能,以确定当前页面是否为最后一页。
还有一个可观察到的触发器,您可以将其绑定到寻呼机(例如,tableview的contentOffset.y与底部的距离),这将触发下一个页面加载(如果next为true)。
答案 1 :(得分:0)
我不确定您的问题是否与RxSwift有关。据我了解,拨打电话时需要使用offset
参数。例如,此请求:
生成以下响应:
{
"count": 964,
"next": "https://pokeapi.co/api/v2/pokemon/?offset=4&limit=4",
"previous": null,
"results": [
{
"name": "bulbasaur",
"url": "https://pokeapi.co/api/v2/pokemon/1/"
},
{
"name": "ivysaur",
"url": "https://pokeapi.co/api/v2/pokemon/2/"
},
{
"name": "venusaur",
"url": "https://pokeapi.co/api/v2/pokemon/3/"
},
{
"name": "charmander",
"url": "https://pokeapi.co/api/v2/pokemon/4/"
}
]
}
看看next
键的值是您接下来应该点击的URL吗?
"next": "https://pokeapi.co/api/v2/pokemon/?offset=4&limit=4",
我相信,只要您跟踪offset
的值,就可以接收所需的数据。