I have the strangest problem. I’ve developed a SwiftUI app for iPhone, iPad and MacCatalyst using Core Data and CloudKit private database to sync the user’s data across all his/her devices.
The problem is that when I make an update on an iOS device (iPhone or iPad), the update syncs across all iOS devices, but not to the Macs. Similarly, updates I make on the Macs, sync across the Macs, but not to the iOS devices.
If I delete the app on the Mac and its associated sqllite database in the app’s associated ~/Library/Container/<myapp_container>/Data subfolder and reinstall the app, only the ?Mac data? gets refilled from CloudKit. Likewise if I delete the app on an iOS device, only the ?iOS data? arrives from CloudKit. In other words, it behaves as if the MacCatalyst data and the iOS data are stored separately in CloudKit.
Now, if I compile the app onto the Mac (rather than installing an Archive app), the sync from the iOS devices go through. But only once. Subsequent updates are not synced until I compile the app onto the Mac again. Likewise, updates made on the Mac only get synced (once) to the iOS devices when I compile the app on the Mac. Recompiling to the iOS devices does not make any difference.
The PersistentCloudkitContainer class:
public class PersistentCloudKitContainer {
// MARK: - Define Constants / Variables
public static var context: NSManagedObjectContext {
return persistentContainer.viewContext
}
// MARK: - Initializer
private init() {}
// MARK: - Core Data stack
public static var persistentContainer: NSPersistentContainer = {
let container = NSPersistentCloudKitContainer(name: "MyModel")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error (error), (error.userInfo)")
}
})
guard let description = container.persistentStoreDescriptions.first else {
fatalError("### PersistentCloudKitContainer->(#function): Failed to retrieve persistant store description")
}
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
description.cloudKitContainerOptions?.databaseScope = .private
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return container
}()
// MARK: - Core Data Saving support
public static func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error (nserror), (nserror.userInfo)")
}
}
}
The persistent container is called by the SwiftUI App struct:
struct MyApp: App {
let context = PersistentCloudKitContainer.persistentContainer.viewContext
var body: some Scene {
WindowGroup {
ContentView().environment(.managedObjectContext, context)
}
}
}
question from:
https://stackoverflow.com/questions/65840660/core-data-cloudkit-sync-problem-on-maccatalyst 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…