How to Drop Entity in SwiftData and CloudKit?

I'm using SwiftData with CloudKit and have been trying to migrate from SchemaV1 to SchemaV2, but it seems reducing the Entities crashes my app.

// Example of migrating from V1 to V2
// Dropping `Person` because it's no longer needed

do {

// SchemaV1: Person.self, Author.self
// SchemaV2: Author.self
let schema = Schema(versionedSchema: SchemaV2.self)

return try ModelContainer(
   for: schema,
   migrationPlan: AppSchemaMigrationPlan.self,
   configurations: ModelConfiguration(
          cloudKitDatabase: .automatic)
    )

} catch {

   fatalError("Could not create ModelContainer: \(error)")

}

Is it possible to drop Entities in the Schema Migration Plan?

How can I delete the Person model from my Schema and CloudKit?

Answered by DTS Engineer in 822046022

Are you on the CloudKit production environment or the development one? On the production environment, you will want to keep the model class there because:

  • CloudKit production environment only supports additive changes, and so the CloudKit schema associated with the SwiftData model will always be there. See Deploying an iCloud Container’s Schema for more information.

  • An app instance with the SchemaV2 may still need to handle SchemaV1 data because a user may not update your app on all their devices simultaneously. Although "handle" here pretty much means "ignore," SwiftData + CloudKit still needs to know that Person is a valid type.

If you are on the development environment, you can try to reset the CloudKit environment, and go from the very beginning.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Accepted Answer

Are you on the CloudKit production environment or the development one? On the production environment, you will want to keep the model class there because:

  • CloudKit production environment only supports additive changes, and so the CloudKit schema associated with the SwiftData model will always be there. See Deploying an iCloud Container’s Schema for more information.

  • An app instance with the SchemaV2 may still need to handle SchemaV1 data because a user may not update your app on all their devices simultaneously. Although "handle" here pretty much means "ignore," SwiftData + CloudKit still needs to know that Person is a valid type.

If you are on the development environment, you can try to reset the CloudKit environment, and go from the very beginning.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Wow! Now I understand, thank you very much. This has been very insightful.

Building up on the previous example, what could be possible causes why didMigrate is not being called?

I wrote a print statement and some code, but it's never run.

    static let migrateV1toV2 = MigrationStage.custom(
        fromVersion: SchemaV1.self,
        toVersion: SchemaV2.self,
        willMigrate: nil, 
        didMigrate: { context in
               print("Running Post Migration")
               // post-migration code here
        }
    )

My current workaround was to run the post-migration code outside the MigrationStage.

I provided a workable code example related SwiftData schema migration in the following post. You might give it a try, and follow up from there, if needed:

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

How to Drop Entity in SwiftData and CloudKit?
 
 
Q