К сожалению, я думаю, что это «нормальное» поведение, особенно с большой базой данных с большим количеством синхронизируемых взаимосвязей - нет никакого способа увидеть прогресс (показать пользователю), и вы не можете его ускорить.
NSPersistentCloudKitContainer
, кажется, рассматривает каждое отношение как отдельное CKRecord
, с синхронизацией, по-прежнему связанной теми же ограничениями (т. Е. Не более 400 «запросов» одновременно), вы часто будете видеть их. ошибки limitExceeded в консоли, но с небольшим количеством другой информации (т. е. если / когда он будет повторяться ??).
Я нахожу эти результаты в базе данных, требующей days для полной синхронизациис данными, выглядящими испорченными и неполными в то же время. У меня тысячи отношений «многие ко многим», и когда пользователь восстанавливает свою базу данных из внешнего файла, все эти CKRecords необходимо воссоздать.
Основная проблема, с которой я столкнулсяздесь нет способа запросить NSPersistentCloudKitContainer
, есть ли ожидающие запросы, сколько еще нужно синхронизировать и т. д., чтобы вы могли передать это пользователям в пользовательском интерфейсе, чтобы они не продолжали удалять и восстанавливать, думая, что это 'Ошибка '.
Один из способов удаления локальных данных при выключении синхронизации - и, возможно, избавление от необходимости повторной синхронизации при повторном включении - это использоватьNSPersistentContainer
, когда он выключен, и NSPersistentCloudKitContainer
, когда он включен.
NSPersistentCloudKitContainer
является подклассом NSPersistentContainer
.
. В настоящее время я делаю это в своем приложении в своем пользовательскомКласс PersistenceService:
static var useCloudSync = UserDefaults.standard.bool(forKey: "useCloudSync")
static var persistentContainer: NSPersistentContainer = {
let container: NSPersistentContainer?
if useCloudSync {
container = NSPersistentCloudKitContainer(name: "MyApp")
} else {
container = NSPersistentContainer(name: "MyApp")
let description = container!.persistentStoreDescriptions.first
description?.setOption(true as NSNumber,
forKey: NSPersistentHistoryTrackingKey)
}
container!.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container!
}()
Это по крайней мере приводит к тому, что локальные данные не затрагиваются при отключении iCloud в вашем приложении и не требуют повторной синхронизации всего при повторном включении.
Думаю Вы также можете запросить iOS, чтобы узнать, отключил ли пользователь iCloud в Системных настройках и переключиться между ними до того, как NSPersistentCloudKitContainer
удалит все локальные данные.
РЕДАКТИРОВАТЬ: добавлен NSPersistentHistoryTrackingKey
как безэто, переключение обратно на NSPersistentContainer
с NSPersistentCloudKitContainer
не удается.
В моем приложении работает должным образом. Когда пользователь повторно включает синхронизацию iCloud в моем приложении (и переключается с NSPersistentContainer
на NSPersistentCloudKitContainer
), он синхронизирует все, что было добавлено / изменено с момента последней синхронизации, что именно то, что я хочу!