我已经设法让 CoreData 与 CloudKit 在我的应用程序的 iOS 版本上与新的 NSPersistentCloudKitContainer 一起工作,并让它在应用程序运行时自动同步。但是,当我在 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 才能工作?任何帮助,将不胜感激。