Как правильно выполнить постоянную очистку истории, не влияя на корректность CloudKit?IOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 Как правильно выполнить постоянную очистку истории, не влияя на корректность CloudKit?

Сообщение Anonymous »

В настоящее время мы используем локальные CoreData с функцией CloudKit, используя NSPersistentCloudKitContainer.
Почему мы включаем функцию постоянного отслеживания истории?< /h2>
Из-за проблемы, описанной в https://stackoverflow.com/a/72554542/72437, нам необходимо включить NSPersistentHistoryTrackingKey.

Очистить историю
На основании https://developer.apple.com/documentati ... re_changes, мы должны выполнить постоянную очистку истории вручную.< /p>

Но не совсем ясно, как мы можем очистить историю безопасным способом, не влияя на корректность CloudKit. Мы обычно проводим несколько тестов со следующей настройкой.
  • Запустите симулятор. Мы выполним операцию вставки в симуляторе.
  • Запустите реальное устройство. Реальное устройство получит автоматическое push-уведомление на этапе 1.
  • И симулятор, и реальное устройство выполняют один и тот же код.
  • Каждый раз, когда мы вставьте элемент в симулятор, и мы посмотрим, что произойдет на реальном устройстве.
Тест 1: Очистка все данные истории сразу после обработки

Код: Выделить всё

@objc func storeRemoteChange(_ notification: Notification) {
// Process persistent history to merge changes from other coordinators.
historyQueue.addOperation {
self.processPersistentHistory()
}
}

/**
Process persistent history, posting any relevant transactions to the current view.
*/
private func processPersistentHistory() {
backgroundContext.performAndWait {

// Fetch history received from outside the app since the last token
let historyFetchRequest = NSPersistentHistoryTransaction.fetchRequest!
historyFetchRequest.predicate = NSPredicate(format: "author != %@", appTransactionAuthorName)
let request = NSPersistentHistoryChangeRequest.fetchHistory(after: lastHistoryToken)
request.fetchRequest = historyFetchRequest

let result = (try? backgroundContext.execute(request)) as? NSPersistentHistoryResult
guard let transactions = result?.result as? [NSPersistentHistoryTransaction] else { return }

...

// Update the history token using the last transaction.
lastHistoryToken = transactions.last!.token

// Remove history before the last history token
let purgeHistoryRequest = NSPersistentHistoryChangeRequest.deleteHistory(before: lastHistoryToken)
do {
try backgroundContext.execute(purgeHistoryRequest)
} catch {
error_log(error)
}
}
}
По нашим наблюдениям, реальное устройство получает неверную информацию о синхронизации CloudKit. Реальное устройство либо получает дублированные данные, либо его данные удаляются.
Наша гипотеза по поводу этой проблемы:
  • Данные истории персистентности распределяются между несколькими координаторами персистентности.
  • Наш видимый координатор завершил обработку транзакции, отметьте запись в LastHistoryToken, а затем очистите все истории старше, чем LastHistoryToken< /code>.
  • Однако существует еще один невидимый координатор, используемый CloudKit для синхронизации. Существует высокая вероятность того, что координатор CloudKit еще не обработал удаленные транзакции истории.
  • Это приводит к тому, что все данные становятся неправильными, когда CloudKit пытается синхронизировать данные реального устройства без необходимой истории транзакций.
Тест 2. Удаление всех данных истории старше 2 минут после обработки< /h2>
Мы настраиваем приведенный выше код, удаляя только историю транзакций старше 2 минут.

Код: Выделить всё

// Remove history older than 2 minutes.
let date = Date(timeMillis: Date.currentTimeMillis - 2*60*1000)
let purgeHistoryRequest = NSPersistentHistoryChangeRequest.deleteHistory(before: date)
do {
try backgroundContext.execute(purgeHistoryRequest)
} catch {
error_log(error)
}
Наше наблюдение заключается в том, что
  • Если разница во времени между последним срабатыванием storeRemoteChange и текущим срабатыванием storeRemoteChange< /code> меньше 2 минут, реальное устройство получит правильную информацию о синхронизации CloudKit.
  • Если разница во времени между последним срабатыванием storeRemoteChange и текущий storeRemoteChange превышает 2 минуты, реальное устройство получит неправильную информацию для синхронизации CloudKit. Реальное устройство либо получает дублированные данные, либо его данные удаляются.
Сводка и вопрос
На основе статьи «Как сократить историю прямо в приложении CoreData+CloudKit?»
Предлагает автор

Поэтому действительно безопасно удалять постоянную историю, скажем, через семь
дней после ее обработки.

Для 1 пользователя: Корпус для 2 устройств.
  • Пользователь часто читает/пишет на своем часто используемом устройстве A.
  • пользователь запустит то же приложение на своем редко используемом устройстве Б через 7 дней с момента последнего использования на устройстве Б.
Означает ли это, что устройство Б будет получать неверную информацию о синхронизации CloudKit? (Похоже, что да, судя по наблюдениям в Тесте 2)
Если да, то каков хороший способ выполнить постоянную очистку истории, не влияя на корректность CloudKit?

Как запустить тест 2?
Вы можете настроить и запустить тест 2
  • Настройте и запустите пример из https://developer.apple.com/documentati ... _the_cloud
  • Замените CoreDataStack.swift на https: //gist.github.com/yccheok/df21f199b81b19764ffbcd4a4583c430. Он содержит вспомогательные функции для даты и код очистки двухминутной истории.
  • В симуляторе создайте 1 записи, коснувшись верхнего правого угла. Вы можете видеть, что на реальном устройстве теперь есть 1 записей.
  • Через 3 минуты снова нажмите в правом верхнем углу. В симуляторе вы можете увидеть всего 2 записи. Однако на реальном устройстве данные исчезли!
[img]https://i.sstatic .net/I9tdR.jpg[/img]
(На этом рисунке левое устройство — настоящее устройство, а правое — симулятор)

Подробнее здесь: https://stackoverflow.com/questions/725 ... ffecting-t
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «IOS»