Предоставляет ли Siesta специальную обработку для нумерации страниц?
Как Siesta обрабатывает постраничные URL? Существует ли механизм управления несколькими страницами результатов как одним ресурсом?
1 ответ
Сиеста не предоставляет никакой специальной обработки для нумерации страниц. Страничные URL ведут себя так же, как и любые другие: каждый URL является уникальным ресурсом. Сиеста не имеет никакой темной магии, чтобы объединить ответы с разных URL-адресов в один ресурс.
Другими словами, если ваша схема нумерации выглядит /dingbats?page=3&per_page=10
Затем Сиеста считает "страницу 3 дингбатов с 10 на страницу" одним ресурсом. Если ваша схема нумерации выглядит /dingbats?since_serial_num=31415&max=20
тогда у Сиесты будет один ресурс для "до 20 дингбатов с серийным номером 31415".
пример
Что это значит на практике? Предположим, например, что ваш API возвращает X-Next-Page
header (упрощенный вариант схемы разбивки на страницы 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. Однако вам не нужно отказываться от Сиесты! Чтобы вернуться к более традиционному подходу на основе запросов, используйте Resource.request(…)
методы вместо load()
а также loadIfNeeded()
:
paginatedResource.request(.GET).success { newData in … }
Это позволяет вам управлять paginatedResource
просит себя, все еще используя кеширование Siesta для других частей API.