Reputation: 4069
In the following link, there is the source code for a project that allows you to sync core data between the same user devices. Data is stored in User Private Database... is there a way to sync data from CoreData in public CloudKit database so the app will be the same between ALL app users? Why NSPersistentCloudKitContainer doesn't allow you to set this?
https://developer.apple.com/documentation/coredata/synchronizing_a_local_store_to_the_cloud
Upvotes: 2
Views: 2532
Reputation: 95
To answer last question in comments, yes it is possible use .public and . private on the same store. This is the link to the project: Messanger by Patrick Maltagliati on 10/2/20
init(inMemory: Bool = false) {
container = NSPersistentCloudKitContainer(name: "Messanger")
let defaultDesctiption = container.persistentStoreDescriptions.first
let url = defaultDesctiption?.url?.deletingLastPathComponent()
let privateDescription = NSPersistentStoreDescription(url: url!.appendingPathComponent("private.sqlite"))
let privateOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.com.Maltagliati.Messanger")
privateOptions.databaseScope = .private
privateDescription.cloudKitContainerOptions = privateOptions
privateDescription.configuration = "Private"
privateDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
privateDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
let publicDescription = NSPersistentStoreDescription(url: url!.appendingPathComponent("public.sqlite"))
let publicOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.com.Maltagliati.Messanger")
publicOptions.databaseScope = .public
publicDescription.cloudKitContainerOptions = publicOptions
publicDescription.configuration = "Public"
publicDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
publicDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.persistentStoreDescriptions = [privateDescription, publicDescription]
if inMemory {
container.persistentStoreDescriptions.forEach { $0.url = URL(fileURLWithPath: "/dev/null") }
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
}
Upvotes: 3
Reputation: 186
This is now possible in iOS 14.0+ Beta and macOS 11.0+ Beta via the new databaseScope property: https://developer.apple.com/documentation/coredata/nspersistentcloudkitcontaineroptions/3580372-databasescope
The possible values are .public
(the public database), .private
(the private database) and .shared
(the shared database).
E.g.:
let container = NSPersistentCloudKitContainer(name: "test")
guard let description = container.persistentStoreDescriptions.first else {
fatalError("Error")
}
description.cloudKitContainerOptions?.databaseScope = .public
The video https://developer.apple.com/videos/play/wwdc2020/10650 describes how to sync the Core Data store with the CloudKit public database by setting the databaseScope value to .public.
You may also need an #available
check to ensure backwards compatibility, ie:
if #available(iOS 14.0, *) {
description.cloudKitContainerOptions?.databaseScope = .public
} else {
// Fallback on earlier versions
}
Upvotes: 8