Is migration working for anyone on Xcode beta6?

Hi,

I am trying my first SwiftData migration, but my custom migration stage never gets called.

Since I am not sure if this is a bug with the current beta of if I am "holding it wrong" I was wondering, if anybody got migration working (their MigrationStage.custom called)? Would be great, if you could just let me know, if you got it working or running into the same issue! :-)

Thank you!

Cheers, Michael

Replies

My migration doesn't currently work, but does get called. In my Object file is the below:

enum TodoSchemaV1: VersionedSchema {
    static var models: [any PersistentModel.Type] {
        [ToDoItem.self]
    }
    
    static var versionIdentifier: String = "Initial version"
    
    @Model
    final class ToDoItem {
        @Attribute(.unique) var id: String
        var timestamp: Date
        var completed: Bool
        var title: String
        var info: String
        
        init(timestamp: Date, completed: Bool, title: String, info: String) {
            self.id = UUID().uuidString
            self.timestamp = timestamp
            self.completed = completed
            self.title = title
            self.info = info
        }
    }
}

enum TodoSchemaV2: VersionedSchema {
    static var versionIdentifier: String = "Adds priority"
    
    static var models: [any PersistentModel.Type] {
        [ToDoItem.self]
    }
    
    @Model
    final class ToDoItem {
        @Attribute(.unique) var id: String
        var timestamp: Date
        var completed: Bool
        var title: String
        var info: String
        var priority: Int
        
        init(timestamp: Date, completed: Bool, title: String, info: String, priority: Int) {
            self.id = UUID().uuidString
            self.timestamp = timestamp
            self.completed = completed
            self.title = title
            self.info = info
            self.priority = priority
        }
    }
}

enum MigrationPlan: SchemaMigrationPlan {
    static var schemas: [any VersionedSchema.Type] {
        [TodoSchemaV1.self, TodoSchemaV2.self]
    }
    
    static var stages: [MigrationStage] {
        [migrateV1toV2]
    }

    static let migrateV1toV2 = MigrationStage.custom(fromVersion: TodoSchemaV1.self, toVersion: TodoSchemaV2.self, willMigrate: { context in
        guard let todoItemsV1 = try? context.fetch(FetchDescriptor<TodoSchemaV1.ToDoItem>()) else {
            return
        }
        
        for item in todoItemsV1 {
            // TODO: Work out how to add the priority value
        }
        
        do {
            try context.delete(model: TodoSchemaV1.ToDoItem.self)
            try context.save()
        } catch {
            context.rollback()
            fatalError("Migrating from v1 to v2 failed")
        }
        
    }, didMigrate: nil)
}

Then where I set up the container

container = try ModelContainer(for: [ToDoItem.self],
                                           migrationPlan: MigrationPlan.self,
                                           ModelConfiguration(for: [ToDoItem.self]))

And then that container is passed to my base view

  • @sophieclark28 Hi, have you worked it out to add a new property in the new model and take the migration? I have the same issue and searched around the SwiftData document, it seems nothing is mentioned there.

Add a Comment