Migrate Core Data to SwiftData in an App Group (& CloudKit)

Hello, I’m upgrading my app from Core Data to SwiftData. Due to my old setup the Core Data store has an explicitly name like „Something.sqlite“, because it was defined via NSPersistentContainer(name: "Something") before switching to SwiftData.

Now my goal is to migrate the Core Data stack to SwiftData, while moving it to an App Group (for Widget support) as well as enable iCloud sync via CloudKit.

Working Migration without App Group & CloudKit

I’ve managed to get my migration running without migrating it to an App Group and CloudKit support like so:

@main
struct MyAppName: App {
    let container: ModelContainer
    
    init() {
        // Legacy placement of the Core Data file.
        let dataUrl = URL.applicationSupportDirectory.appending(path: "Something.sqlite")
        
        do {
            // Create SwiftData container with migration and custom URL pointing to legacy Core Data file
            container = try ModelContainer(
                for: Foo.self, Bar.self,
                migrationPlan: MigrationPlan.self,
                configurations: ModelConfiguration(url: dataUrl))
        } catch {
            fatalError("Failed to initialize model container.")
        }
    }

    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(container)
    }
}

How To Migrate to App Group & CloudKit?

I’ve already tried to use the ModelConfiguration with a name, but it seems to only look for a .store file and thus doesn’t copy over the Core Data contents.

let fullSchema = Schema([Foo.self, Bar.self])
        
let configuration = ModelConfiguration("Something", schema: fullSchema)

Can someone help me how to do this migration or point me into the right direction? I can’t find anything relating this kind of migration …

Answered by DTS Engineer in 790031022

It sounds like you've successfully migrated your data from CoreData to SwiftData. To summarize, you successfully migrated from CoreData to SwiftData, but you're having trouble syncing the new SwiftData container due to the configuration and the default .store name created by SwiftData after migrating from a .sqlite file. However, you're encountering issues syncing the new SwiftData container due to the configuration changes and the default .store name created by SwiftData during the migration.

Specifically, SwiftData automatically generates a .store file after migration from a .sqlite file. But in your case, you want to keep the existing .sqlite file name. Here are the steps you can follow:

  1. Update your SwiftData configuration: After completing the migration, you need to specify the file name extension to SwiftData. To do this, change the name property in the ModelConfiguration to include the .sqlite extension, after you rename it:
let configuration = ModelConfiguration("Something.sqlite", schema: fullSchema)
  • This step is crucial if you want to keep the existing .sqlite file name if that’s what you want to do.
  1. Move and open the new database: After adjusting the configuration, you'll need to move the new .store database file (which was created during migration) and rename it to ".sqlite". Then, open it using the updated configuration.

Following these two steps should get you back on track.

Now, to add iCloud support to the existing SwiftData container, follow this guide: https://developer.apple.com/documentation/swiftdata/syncing-model-data-across-a-persons-devices.

I believe you are almost there. Your modifications to the model were correct. If you could post your model here for review, it would be helpful. Additionally, ensuring that you have correctly set up iCloud support in your Xcode project is essential.

Specifically, in your Xcode project, you need to:

  • Enable iCloud CloudKit services
  • Add the SwiftData container to the iCloud container list

Let me know if you have any further questions or if there are any errors in your model configuration.

It sounds like you've successfully migrated your data from CoreData to SwiftData. To summarize, you successfully migrated from CoreData to SwiftData, but you're having trouble syncing the new SwiftData container due to the configuration and the default .store name created by SwiftData after migrating from a .sqlite file. However, you're encountering issues syncing the new SwiftData container due to the configuration changes and the default .store name created by SwiftData during the migration.

Specifically, SwiftData automatically generates a .store file after migration from a .sqlite file. But in your case, you want to keep the existing .sqlite file name. Here are the steps you can follow:

  1. Update your SwiftData configuration: After completing the migration, you need to specify the file name extension to SwiftData. To do this, change the name property in the ModelConfiguration to include the .sqlite extension, after you rename it:
let configuration = ModelConfiguration("Something.sqlite", schema: fullSchema)
  • This step is crucial if you want to keep the existing .sqlite file name if that’s what you want to do.
  1. Move and open the new database: After adjusting the configuration, you'll need to move the new .store database file (which was created during migration) and rename it to ".sqlite". Then, open it using the updated configuration.

Following these two steps should get you back on track.

Now, to add iCloud support to the existing SwiftData container, follow this guide: https://developer.apple.com/documentation/swiftdata/syncing-model-data-across-a-persons-devices.

I believe you are almost there. Your modifications to the model were correct. If you could post your model here for review, it would be helpful. Additionally, ensuring that you have correctly set up iCloud support in your Xcode project is essential.

Specifically, in your Xcode project, you need to:

  • Enable iCloud CloudKit services
  • Add the SwiftData container to the iCloud container list

Let me know if you have any further questions or if there are any errors in your model configuration.

Migrate Core Data to SwiftData in an App Group (& CloudKit)
 
 
Q