我已经成功地在我的iOS应用程序中使用新的NSPersistentCloudKitContainer实现了与CloudKit的CoreData集成,并使其能够在应用程序运行时自动同步。但是,当我尝试在watchOS应用程序上设置时,我发现只有在我强制关闭并重新打开手表应用程序时才会发生同步。
import Foundation
import CoreData
class DataManager : NSObject {
static let shared = DataManager()
#if os(watchOS)
let transactionAuthorName = "watchOSApp"
#else
let transactionAuthorName = "iOSApp"
#endif
override private init() {
super.init()
}
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentCloudKitContainer(name: "Model")
let cloudStoreUrl = applicationDocumentDirectory()!.appendingPathComponent("product.sqlite")
let cloudStoreDescription = NSPersistentStoreDescription(url: cloudStoreUrl)
cloudStoreDescription.shouldInferMappingModelAutomatically = true
cloudStoreDescription.shouldMigrateStoreAutomatically = true
cloudStoreDescription.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions(containerIdentifier:"iCloud.com.company.product")
container.persistentStoreDescriptions = [cloudStoreDescription]
container.loadPersistentStores(completionHandler: { storeDescription, error in
if let error = error as NSError? {
print("Error loading store. \(error)")
}
})
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
container.viewContext.automaticallyMergesChangesFromParent = true
try? container.viewContext.setQueryGenerationFrom(.current)
container.viewContext.transactionAuthor = transactionAuthorName
return container
}()
}
// MARK: - Core Data
extension DataManager {
func applicationDocumentDirectory() -> URL? {
return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier:"group.shiningdevelopers.h2o")
}
func managedObjectContext() -> NSManagedObjectContext {
return persistentContainer.viewContext
}
func reset() {
managedObjectContext().reset()
}
func saveContext () {
let context = managedObjectContext()
if context.hasChanges {
do {
try context.save()
} catch let error as NSError {
// Replace this implementation with code to handle the error appropriately.
// Log this error for now to be able to glean more information
print("Could not save. \(error), \(error.userInfo)")
}
}
}
}
以下情况可以正常工作:
- 用户同时运行watchOS应用程序和iOS应用程序。
- 用户在手表应用程序上更改数据。
- 更改会反映在iOS应用程序上。
- 用户仅运行iOS应用程序。
- 用户在iOS应用程序上更改数据。
- 用户从终止状态打开watchOS应用程序。
- 更改将反映在watchOS应用程序上。以下情况无法正常工作: - 用户同时运行watchOS应用程序和iOS应用程序。 - 用户在iOS应用程序上更改数据。 - 即使等待很长时间,也不会有任何变化传递到watchOS应用程序中。 - 只有在我强制关闭应用程序并重新启动后才会发生同步。
在同步成功的情况下,我正确地看到以下日志:
CoreData: debug: CoreData+CloudKit:
-[PFCloudKitImporterZoneChangedWorkItem newMirroringResultByApplyingAccumulatedChanges:]_block_invoke_2(243): <PFCloudKitImporterZoneChangedWorkItem: 0x16530fb0> { ( "<CKRecordZoneID: 0x1656a920; zoneName=com.apple.coredata.cloudkit.zone, ownerName=__defaultOwner__>" ) } - Importing updated records: ( "<CKRecord: 0x16526280; recordType=CD_LogEntry, values={\n "CD_day" = 15;\n "CD_entityName" = LogEntry;\n "CD_glassesGoal" = 8;\n "CD_glassesLogged" = 13;\n "CD_lastModified" = "2019-09-15 18:56:08 +0000";\n "CD_month" = 9;\n "CD_year" = 2019;\n}, recordChangeTag=7d, recordID=2180D6A3-ACFC-4421-8CAF-6EE288DAAC2E:(com.apple.coredata.cloudkit.zone:defaultOwner)>" ) Deleted RecordIDs: {
}
然而,在最后的场景中,我没有看到任何日志,完全没有声音。我在应用程序的iOS和watchOS版本中共享相同的CoreData / CloudKit代码。我还使用了NSFetchedResultsController来确保我的UI保持最新状态,在iOS应用程序上似乎可以工作,但在watchOS应用程序上却不行。不确定在设置手表扩展时是否有些步骤遗漏了。
有人成功实现了与watchOS的同步吗?任何帮助将不胜感激。