In Core data public configuration, added new attribute to entities, new entities, but the changes are neither synchronized nor data is transferred to existing container schema in cloudkit.
private var _publicPersistentStore: NSPersistentStore?
var publicPersistentStore: NSPersistentStore {
return _publicPersistentStore!
}
private var _privatePersistentStore: NSPersistentStore?
var privatePersistentStore: NSPersistentStore {
return _privatePersistentStore!
}
private var _sharedPersistentStore: NSPersistentStore?
var sharedPersistentStore: NSPersistentStore {
return _sharedPersistentStore!
}
static let shared = PersistenceController()
static var preview: PersistenceController = {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
do {
try viewContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
return result
}()
let container: NSPersistentCloudKitContainer
init(inMemory: Bool = false) {
container = NSPersistentCloudKitContainer(name: “GS”)
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
guard let defaultDescription = container.persistentStoreDescriptions.first else {
fatalError("###\(#function): failed to retrieve a persistent store description.")
}
let containerIdentifier = defaultDescription.cloudKitContainerOptions!.containerIdentifier
print(containerIdentifier)
print(defaultDescription.url as Any)
let url = defaultDescription.url?.deletingLastPathComponent()
print(url as Any)
// Public
let publicDescription = NSPersistentStoreDescription(url: url!.appendingPathComponent("public.sqlite"))
publicDescription.configuration = "Public"
print(publicDescription.url)
let publicOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: containerIdentifier)
publicOptions.databaseScope = .public
publicDescription.cloudKitContainerOptions = publicOptions
publicDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
publicDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
// Private
let privateDescription = NSPersistentStoreDescription(url: url!.appendingPathComponent("private.sqlite"))
privateDescription.configuration = "Private"
print(privateDescription.url)
let privateOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: containerIdentifier)
privateOptions.databaseScope = .private
privateDescription.cloudKitContainerOptions = privateOptions
privateDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
privateDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
// Shared
guard let sharedDescription = privateDescription.copy() as? NSPersistentStoreDescription else {
fatalError("#\(#function): Copying the private store description returned an unexpected value.")
}
sharedDescription.url = url!.appendingPathComponent("shared.sqlite")
print(sharedDescription.url)
sharedDescription.configuration = "Shared"
let sharedOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: containerIdentifier)
sharedOptions.databaseScope = .shared
sharedDescription.cloudKitContainerOptions = sharedOptions
sharedDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
sharedDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.persistentStoreDescriptions = [publicDescription, privateDescription, sharedDescription]
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
else {
if let cloudKitContainerOptions = storeDescription.cloudKitContainerOptions {
if #available(iOS 16.0, *) {
if .public == storeDescription.cloudKitContainerOptions?.databaseScope {
print("loaded public store")
// self._publicPersistentStore = container.persistentStoreCoordinator.persistentStore(for: storeDescription.url!)
} else if .private == storeDescription.cloudKitContainerOptions?.databaseScope {
print("loaded private store")
//self._privatePersistentStore = container.persistentStoreCoordinator.persistentStore(for: storeDescription.url!)
} else if .shared == storeDescription.cloudKitContainerOptions?.databaseScope {
print("loaded shared store")
//self._sharedPersistentStore = container.persistentStoreCoordinator.persistentStore(for: storeDescription.url!)
}
} else {
// Fallback on earlier versions
}
}
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy // external changes trumping in-memory changes.
}
func save() {
let context = container.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Show some error here
print("save error")
}
}
}
}
Tried new container on cloudkit, problem persists. Working previously until I updated Xcode to 15.2 and iOs 16.2. Can you please tell me why coredata is not synchronized for public configuration.
The above code works if the coredata entity is in private configuration, synchronization to cloud kit and data transfer works correctly. The only problem is that it does not synchronize and transfer data from public coredata configured entities to cloudkit. At a loss to understand why
A core data entity in the same configuration got synchronized with cloudKit after a delay of one day. Is there a wait time for synchronization?