Post

Replies

Boosts

Views

Activity

Record Duplication Issue When Migrating NSPersistentCloudKitContainer Persistent Store Location
Hi there! I built an app using Core Data and CloudKit using NSPersistentCloudKitContainer - https://developer.apple.com/documentation/coredata/nspersistentcloudkitcontainer. However, now that I'm looking to add support for extensions, I need to migrate the existing store from its default location using migratePersistentStore(_:to:options:withType:) - https://developer.apple.com/documentation/coredata/nspersistentstorecoordinator/1468927-migratepersistentstore so it can be accessed from a new App Group. Once I update the app to the new build with the migration logic, the store appears empty to CloudKit and the existing objects are re-downloaded to the device. This effectively duplicates all of the records. It seems as though the migrated records are new NSManagedObjects, which would explain why CloudKit doesn't have a corresponding CKRecord. Upon detecting that the CloudKit version of the object does not exist on device, NSPersistentCloudKitContainer ensures that it is created (appearing to the user as a duplicate). Is there a way to handle this apparent duplication or to link up the migrated local records to the corresponding CKRecords? Any advice on ensuring that this migration goes smoothly for users with existing app data in iCloud? This is how I currently have my container set up: let container = NSPersistentCloudKitContainer(name: containerName) var defaultURL: URL? if let storeDescription = container.persistentStoreDescriptions.first, let url = storeDescription.url {     defaultURL = FileManager.default.fileExists(atPath: url.path) ? url : nil } /* If the file does not exist, set the description to use the shared store */ let description: NSPersistentStoreDescription if let defaultURL = defaultURL {     description = NSPersistentStoreDescription(url: defaultURL) } else {     description = NSPersistentStoreDescription(url: appGroupURL) } description.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: cloudContainerId) description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) container.persistentStoreDescriptions = [description] container.loadPersistentStores { ... } container.viewContext.automaticallyMergesChangesFromParent = true container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy return container  After creating the container, I run the method to migrate the store if the old store location was used (i.e. if the defaultURL is not null). Once the migration is complete, I re-create the NSPersistentContainer using the above function, which will use the shared appGroupURL since the store at the defaultURL was deleted. Shortly after setting the new container, the records are fetched from CloudKit automatically, which is where I'm running into my issue. Thanks!
3
2
2k
Jul ’20