Разбор локального хранилища данных + сетевая синхронизация

Я использую Parse.com с моим приложением iOS (написанным на Swift) с 6 месяцев, и я хотел бы использовать Parse local Datastore по многим причинам:

  • Сделайте мое приложение пригодным для использования (извлекаемым) в автономном режиме
  • Сокращение использования данных (многие запросы возвращают "не обновленные данные")
  • Сократить время загрузки (в основном при запуске приложения и загрузке всех данных из сети)

Чтобы сделать это, я хотел бы написать глобальную функцию, управляющую этими сценариями для всего запроса, который я делаю из моего приложения.

У меня уже есть конкретное представление о том, что должна делать функция, но я не знаю, как технически написать эту функцию:)

Сценарии:

  • Зарегистрироваться / Войти (цепочка нескольких запросов):

    1. Получить данные из сети
    2. Сохранить дату в переменной "lastUpdateLocalDatastore" в NSUserDefaults
    3. Данные булавки в локальном хранилище данных
    4. Отображение данных из локального хранилища данных -> ВОЗВРАТ и обновление TableView
  • Загрузка приложения (цепочка нескольких запросов):

    1. Отображение данных из локального хранилища данных -> ВОЗВРАТ и обновление TableView
    2. Получить данные из сети (где "lastUpdateDate" в Parse новее, чем "lastUpdateLocalDatastore" из NSUserDefault)
    3. Данные булавки в локальном хранилище данных
    4. Показать обновленные данные из Local Datastore -> RETURN & update TableView
  • Триггерное обновление (простой запрос):

    1. Получить данные из сети (где "lastUpdateDate" в Parse новее, чем "lastUpdateLocalDatastore" из NSUserDefault)
    2. Данные булавки в локальном хранилище данных
    3. Показать обновленные данные из Local Datastore -> RETURN & update TableView
  • Выйти:

    1. Открепить все данные в локальном хранилище данных
    2. Очистить значения "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
    }
}

Проблемы:

  1. Как обрабатывать множественные (асинхронные) возвраты
  2. Как сделать функцию способной связывать несколько запросов (например, мне нужно извлекать данные из 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", чтобы получать только измененные данные из сети.

Другие вопросы по тегам