Разбор локального хранилища данных + сетевая синхронизация
Я использую Parse.com с моим приложением iOS (написанным на Swift) с 6 месяцев, и я хотел бы использовать Parse local Datastore по многим причинам:
- Сделайте мое приложение пригодным для использования (извлекаемым) в автономном режиме
- Сокращение использования данных (многие запросы возвращают "не обновленные данные")
- Сократить время загрузки (в основном при запуске приложения и загрузке всех данных из сети)
Чтобы сделать это, я хотел бы написать глобальную функцию, управляющую этими сценариями для всего запроса, который я делаю из моего приложения.
У меня уже есть конкретное представление о том, что должна делать функция, но я не знаю, как технически написать эту функцию:)
Сценарии:
Зарегистрироваться / Войти (цепочка нескольких запросов):
- Получить данные из сети
- Сохранить дату в переменной "lastUpdateLocalDatastore" в NSUserDefaults
- Данные булавки в локальном хранилище данных
- Отображение данных из локального хранилища данных -> ВОЗВРАТ и обновление TableView
Загрузка приложения (цепочка нескольких запросов):
- Отображение данных из локального хранилища данных -> ВОЗВРАТ и обновление TableView
- Получить данные из сети (где "lastUpdateDate" в Parse новее, чем "lastUpdateLocalDatastore" из NSUserDefault)
- Данные булавки в локальном хранилище данных
- Показать обновленные данные из Local Datastore -> RETURN & update TableView
Триггерное обновление (простой запрос):
- Получить данные из сети (где "lastUpdateDate" в Parse новее, чем "lastUpdateLocalDatastore" из NSUserDefault)
- Данные булавки в локальном хранилище данных
- Показать обновленные данные из Local Datastore -> RETURN & update TableView
Выйти:
- Открепить все данные в локальном хранилище данных
- Очистить значения "lastUpdate" в NSUserDefault
Функциональная структура:
IF ( "First login" -> Local Datastore is empty ) {
Get data from Network
Pin data in Local Datastore
Save « lastUpdateLocalDatastore » in NSUSerDefaults
—> RETURN data in Cache
} ELSE {
IF ( "Launching application" -> Cache is empty ) {
Get data from Local Datastore
—> RETURN data in Cache
} ELSE IF ( "trigger update" ) {
Get data from Network
Pin new data in Local Datastore
Save « lastUpdateLocalDatastore » in NSUSerDefaults
—> RETURN data in Cache
}
}
Проблемы:
- Как обрабатывать множественные (асинхронные) возвраты
- Как сделать функцию способной связывать несколько запросов (например, мне нужно извлекать данные из 6 разных запросов при загрузке приложения)
1 ответ
Наконец, я нашел способ сделать это, основываясь на этой теме GitHub: https://github.com/ParsePlatform/ParseUI-iOS/issues/53
Вот функция, которую я использую:
func findObjectsLocallyThenRemotely(query: PFQuery!, block:[AnyObject]! -> Void) {
let localQuery = (query.copy() as! PFQuery).fromLocalDatastore()
localQuery.findObjectsInBackgroundWithBlock({ (locals, error) -> Void in
if (error == nil) {
println("Success : Local Query", msg: "\(query.parseClassName)")
block(locals)
} else {
println("Error : Local Query", msg: "\(query.parseClassName)", error: error)
}
query.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
if(error == nil) {
println("Success : Network Query", msg: "\(query.parseClassName)")
PFObject.unpinAllInBackground(locals, block: { (success, error) -> Void in
if (error == nil) {
println("Success : Unpin Local Query", msg: "\(query.parseClassName)")
block(objects)
PFObject.pinAllInBackground(objects, block: { (success, error) -> Void in
if (error == nil) {
println("Success : Pin Query Result", msg: "\(query.parseClassName)")
} else {
println("Error : Pin Query Result", msg: "\(query.parseClassName)", error: error)
}
})
} else {
println("Error : Unpin Local Query", msg: "\(query.parseClassName)", error: error)
}
})
} else {
println("Error : Network Query", msg: "\(query.parseClassName)", error: error)
}
})
})
}
ЧТО ДЕЛАТЬ: Мне нужно добавить опцию "lastUpdateDate", чтобы получать только измененные данные из сети.