Siesta如何处理分页的URL?是否有一种机制可以将多页结果作为单个资源进行管理?
Siesta 不提供任何特殊处理。分页 URL 的行为与其他任何 URL 一样:每个 URL 都是唯一的资源。午睡没有任何黑魔法将来自不同URL的响应合并到单个资源中。
换句话说,如果你的分页方案看起来像 /dingbats?page=3&per_page=10
,那么 Siesta 认为"丁蝙蝠的第 3 页,每页 10 个"是单个资源。如果您的分页方案看起来像 /dingbats?since_serial_num=31415&max=20
,那么 Siesta 将有一个资源用于"自序列号 20 以来最多 31415 个 dingbats"。
例
这在实践中意味着什么?例如,假设您的 API 返回一个 X-Next-Page
标头(Github 分页方案的简化版本(,并且您希望将结果合并到单个可无限滚动的表视图中。
您可以执行以下操作:
private var firstPageOfDingbats: Resource?
private var dingbats: [Dingbat] = []
private var dingbatsDisplayed: Int = 1
func resourceChanged(resource: Resource, event: ResourceEvent) {
refreshPages()
}
func refreshPages() {
// Naive implementation reconstructs the entire dingats array
// with each update — which is probably just fine, since array
// concatenation is cheap.
dingbats.removeAll()
var nextPage = firstPageOfDingbats
while let curPage = nextPage {
// This is a noop if data is up to date, but triggers a
// that runs down the list if it needs updating.
curPage.loadIfNeeded()
// Assuming you’ve set up a content transformer to parse
// the response as [Dingbat], you can pull them out of
// the Resource cheaply.
dingbats.appendContentsOf(
curPage.contentAsType(ifNone: [Dingbat]()))
// Don’t fetch everything if we’ve covered as far as the
// user has scrolled.
if dingbats.count >= dingbatsDisplayed {
break
}
// If we have data and there’s another page, keep going!
nextPage = curPage.optionalRelative(
curPage.latestData?.header("X-Next-Page"))
}
tableView.reloadData()
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dingbats.count
}
// etc.
// Add code to increase dingbatsDisplayed and call refreshPages()
// when user scrolls to the bottom
如果已经存在数据并且一切都是最新的,Siesta 的缓存会使页面的这种天真遍历运行得非常快,但当事情过时时会触发一连串更新。
例如,如果您知道旧条目永远不会更改,而新条目只会出现在顶部,则可以执行更智能的阵列更新。这取决于您使用的特定 API 及其提供的保证。
绕过 Siesta 的缓存
如果您有一个复杂的更新方案,并且想要对请求的内容以及如何将结果保存在内存中进行细粒度控制,那么您可能希望完全绕过 Siesta 的资源缓存。但是,您不需要放弃午睡来做到这一点!要回退到更传统的基于请求的方法,请使用 Resource.request(…)
方法而不是 load()
和 loadIfNeeded()
:
paginatedResource.request(.GET).success { newData in … }
这使您可以自己管理paginatedResource
请求,同时仍将Siesta的缓存用于API的其他部分。