Синхронизация watchOS/CloudKit и фона

#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 является резервной копией.