SwiftData ModelConfigurations always sync to iCloud if one of them has iCloud enabled

I'm facing a weird issue with SwiftData. I want to have one database that's local to the device and one that syncs to iCloud. In this example, LTRLink should be synced via iCloud while LTRMetadata should stay on-device only. I've it configured like the following:

let schema = Schema([LTRLink.self, LTRMetadata.self])
let cloudkitConfiguration = ModelConfiguration("Remote",
                                               schema: schema,
                                               url: FileManager.remoteDatabaseFolderURL.appending(path: "Remote.sqlite"),
                                               cloudKitDatabase: .private("iCloud.com.xavimoll.abyss3"))

let localConfiguration = ModelConfiguration("Local",
                                            schema: schema,
                                            url: FileManager.localDatabaseFolderURL.appending(path: "Local.sqlite"),
                                            cloudKitDatabase: .none)

return try ModelContainer(for: schema,
                          configurations: [cloudkitConfiguration, localConfiguration])

For some reason, when I create the iCloud schema, both models end up appearing as records on iCloud. I create the schema like this:

let schema = Schema([LTRLink.self, LTRMetadata.self])
let cloudkitConfiguration = ModelConfiguration("Remote",
                                               schema: schema,
                                               url: FileManager.remoteDatabaseFolderURL.appending(path: "Remote.sqlite"),
                                               cloudKitDatabase: .private("iCloud.com.xavimoll.abyss3"))
#if DEBUG
// Needed to create the schema on iCloud
try autoreleasepool {
  let desc = NSPersistentStoreDescription(url: cloudkitConfiguration.url)
  let opts = NSPersistentCloudKitContainerOptions(containerIdentifier: cloudkitConfiguration.cloudKitContainerIdentifier!)
  desc.cloudKitContainerOptions = opts
  desc.shouldAddStoreAsynchronously = false
  if let mom = NSManagedObjectModel.makeManagedObjectModel(for: [LTRLink.self]) {
    let container = NSPersistentCloudKitContainer(name: "Remote", managedObjectModel: mom)
    container.persistentStoreDescriptions = [desc]
    container.loadPersistentStores {_, err in
      if let err {
        fatalError(err.localizedDescription)
      }
    }
    try container.initializeCloudKitSchema()
    if let store = container.persistentStoreCoordinator.persistentStores.first {
      try container.persistentStoreCoordinator.remove(store)
    }
  }
}
#endif

let localConfiguration = ModelConfiguration("Local",
                                            schema: schema,
                                            url: FileManager.localDatabaseFolderURL.appending(path: "Local.sqlite"),
                                            cloudKitDatabase: .none)

return try ModelContainer(for: schema,
                          configurations: [cloudkitConfiguration, localConfiguration])

The logic to initialize the CloudKit schema follows the documentation found here: https://developer.apple.com/documentation/swiftdata/syncing-model-data-across-a-persons-devices#Initialize-the-CloudKit-development-schema

It looks like setting cloudKitDatabase: .none on the init for the ModelConfiguration doesn't do anything, and ends up being synced with iCloud either way. When I go to the iCloud console, I see the following:

Does anyone know if there's any workaround that would allow me to have two databases where only one of them syncs to iCloud when using SwiftData?

Answered by xmollv in 811249022

Turns out, this was my own issue! I was passing the schema on both ModelConfigurations, when I should be passing a different Schema for each configuration, and then a Schema that contains everything to the ModelContainer init. I made such change, and now it works as expected, only the LTRLink appear on iCloud's console!

Accepted Answer

Turns out, this was my own issue! I was passing the schema on both ModelConfigurations, when I should be passing a different Schema for each configuration, and then a Schema that contains everything to the ModelContainer init. I made such change, and now it works as expected, only the LTRLink appear on iCloud's console!

SwiftData ModelConfigurations always sync to iCloud if one of them has iCloud enabled
 
 
Q