#swift #xcode #cloudkit #watchos #nspersistentcloudkitcontainer
Вопрос:
Я работаю над приложением Swift, которое работает на iOS, macOS и watchOS (Xcode) с использованием CloudKit (см. Код для инициализации контейнера CloudKit-Persistency ниже). Приложение отлично работает: данные синхронизируются через iCould на всех устройствах.
Моя проблема: синхронизация/зеркальное отображение на watchOS происходит довольно медленно…и watchOS должен быть открыт. Есть ли способ обработать синхронизацию/зеркальное отображение на watchOS в фоновом режиме (автоматически)? Для iOS я добавил «Фоновую выборку» и «Фоновую обработку» в определение цели приложения…не существует для watchOS 🙁
Спасибо и с наилучшими пожеланиями, Ларс.
init(inMemory: Bool = false) {
container = NSPersistentCloudKitContainer(name: "TestersTest")
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
let l_store = NSPersistentContainer.defaultDirectoryURL()
print(l_store)
guard let description = container.persistentStoreDescriptions.first else {
fatalError("###(#function): Failed to retrieve a persistent store description.")
}
let url = container.persistentStoreDescriptions.first!.url
print(url!)
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
container.viewContext.undoManager = nil
container.viewContext.shouldDeleteInaccessibleFaults = true
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
description.setOption(true as NSNumber, forKey: NSMigratePersistentStoresAutomaticallyOption)
description.setOption(true as NSNumber, forKey: NSInferMappingModelAutomaticallyOption)
container.viewContext.transactionAuthor = "TestersTest"
try? container.viewContext.setQueryGenerationFrom(.current)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error (error), (error.userInfo)")
}
})
NotificationCenter.default.addObserver(self, selector: #selector(backgroundContextDidSave(notification:)), name: .NSManagedObjectContextDidSave, object: nil)
print( "merge policy: (container.viewContext.mergePolicy)" )
backgoundContext = container.newBackgroundContext()
print( "merge policy background: (backgoundContext!.mergePolicy)" )
backgoundContext!.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
backgoundContext!.automaticallyMergesChangesFromParent = true
backgoundContext!.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
backgoundContext!.undoManager = nil
backgoundContext!.shouldDeleteInaccessibleFaults = true
print( "merge policy background: (backgoundContext!.mergePolicy)" )
}
Комментарии:
1.Я столкнулся с той же проблемой и в конечном итоге отправил данные из приложения для телефона через
WatchConnectivity
WCSession.default.sendMessage
, если приложение для часов работает, иWCSession.default.updateApplicationContext
в противном случае. Таким образом, приложение watch получает данные сразу, не полагаясь исключительно на синхронизацию iCloud.2. Спасибо тебе, Дамиан. Таким образом, вы заменяете хранение/управление данными на часах с помощью CloudKit доступом к данным на iPhone через WatchConnectivity. Я тоже думал об этом…должно работать, но много отдельного кодирования для watchOS. Хорошая вещь с Xcode/SwiftUI заключается в том, что один и тот же код (и даже пользовательский интерфейс) можно использовать для всех устройств (часы, телефон, mac). Использование WatchConnectivity вместо CloudKit нарушает этот подход 🙁
3. На самом деле я делаю и то, и другое — я обнаружил, что для некоторых пользователей по некоторым причинам синхронизация iCloud занимает много времени или никогда не происходит, поэтому WatchConnectivity является резервной копией.