Migrating schemas in SwiftData + CloudKit

Hello,

I’m struggling to go from unversioned data model in SwiftData, to starting to version it.

Some FYI:

  • I’m using CloudKit
  • I’m using a widget, where I also pass in my data model and setup my container, this is shared over a group container/app group.

My migration is very simple, I’m adding a property which is not optional ( has default value set, and a default value in initialiser ).

Model:

@Model
 class NicotineModel {
     var nicotineType: NicotineType = NicotineType.snus
     var startDate: Date = Date() + 30
     var spendingAmount: Int = 0
     var nicotinePerDay: Int = 0
     var quittingMethod: QuittingMethod = QuittingMethod.coldTurkey // this is the change in the model, V1 doesn't have the quittingMethod property
     
     var setupComplete: Bool = false

I’ve tried with:

static let migrateV1toV2 = MigrationStage.lightweight(
       fromVersion: SchemaV1.self,
       toVersion: SchemaV2.self
   )

But also

   static let migrateV1toV2 = MigrationStage.custom(
       fromVersion: SchemaV1.self,
       toVersion: SchemaV2.self,
       willMigrate: nil,
       didMigrate: {
           context in
           let nicotineModels2 = try context.fetch(FetchDescriptor<SchemaV2.NicotineModel>())
           let nicotineModels = try context.fetch(FetchDescriptor<SchemaV1.NicotineModel>())
           
           
           for model in nicotineModels {
               let newModel = SchemaV2.NicotineModel(
                   nicotineType: model.nicotineType,
                   startDate: model.startDate,
                   spendingAmount: model.spendingAmount,
                   nicotinePerDay: model.nicotinePerDay,
                   setupComplete: model.setupComplete,
                   quittingMethod: .coldTurkey
               )
               
               context.insert(newModel)
               context.delete(model)
           }

           try context.save()
       }
   )

and simply

static let migrateV1toV2 = MigrationStage.custom(
       fromVersion: SchemaV1.self,
       toVersion: SchemaV2.self,
       willMigrate: nil,
       didMigrate: { context in
           let nicotineModels = try context.fetch(FetchDescriptor<SchemaV2.NicotineModel>())
           
           for model in nicotineModels {
               model.quittingMethod = .coldTurkey
           }

           try context.save()
       }
   )

This gives me the error on startup

SwiftData/ModelCoders.swift:1762: Fatal error: Passed nil for a non-optional keypath \NicotineModel.quittingMethod

On https://icloud.developer.apple.com I can see that the record doesn't include my quittingMethod.

I'm loosing my mind, what am I doing wrong?

Did you try without a custom migration, since the property has a default value it should work automatically?

I have the same problem, apparently there is a bug and the custom migration doesn't work if you are using CloudKit. I have the same situation and i am going to try lightweight migration and hope it will get fixed soon.

Migrating schemas in SwiftData + CloudKit
 
 
Q