SwiftData in iOS 26

Dec 10 2025 · Swift 6.2, iOS 26, macOS 26, Xcode 26

Lesson 04: Updates to Schema Migration

Migrating a Schema Demo

Episode complete

Play next episode

Next

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

This demo is going to be performed in stages. Since you are working with code for schema migration, you need two versions, one to migrate from and another for the final version of the schema.

Setup the first version

To setup the first schema model, open the starter project for this lesson, which is mostly a copy of the final project from Lesson 1, which dealt with Recipe model types only. The one change is that the NavigationStack is now in the body for ContentView instead of inside the #Preview block. This ensures the NavigationStack is shown in the simulator.

enum RecipesSchemaV1: VersionedSchema {
  static var versionIdentifier: Schema.Version { Schema.Version(1, 0, 0) }
  static var models: [any PersistentModel.Type] {
    [Recipe.self, Ingredient.self]
  }
}
let modelContainer: ModelContainer = {
  var container: ModelContainer
  do {
    let schema = Schema(versionedSchema: RecipesSchemaV1.self)
    container = try ModelContainer(for: schema)
    return container
  } catch {
    fatalError("Could not create ModelContainer: \(error)")
  }
}()
ContentView()
  .modelContainer(modelContainer)
for recipe in Recipe.sampleData {
  modelContext.insert(recipe)
}

Setup the final version

To setup the second schema model, open up the intermediate project for this lesson. This is the same as the final project from lesson 3, except it also has the VersionedSchema changes we made to the starter project earlier.

@available(iOS 26, *)
enum RecipesSchemaV2: VersionedSchema {
  static var versionIdentifier: Schema.Version { Schema.Version(2, 0, 0) }

  static var models: [any PersistentModel.Type] {
    [
      Recipe.self,
      Ingredient.self,
      BakedGood.self,
      Beverage.self
    ]
  }
}
enum RecipesMigrationPlan: SchemaMigrationPlan {
  static var schemas: [any VersionedSchema.Type] {
    var currentSchemas: [any VersionedSchema.Type] =
    [RecipesSchemaV1.self]
    if #available(iOS 26, *) {
      currentSchemas.append(RecipesSchemaV2.self)
    }
    return currentSchemas
  }
@available(iOS 26, *)
static let migrateV1toV2 = MigrationStage.lightweight(
  fromVersion: RecipesSchemaV1.self,
  toVersion: RecipesSchemaV2.self
)

static var stages: [MigrationStage] {
  var currentStages: [MigrationStage] = []
  if #available(iOS 26, *) {
    currentStages.append(migrateV1toV2)
  }
  return currentStages
  }
}

Perform the migration

Up to now, this module has worked inside the Xcode Canvas. For this migration example, the simulator will be used instead. I have the iPhone16 Pro simulator up on the right side of the screen, and there isn’t a version of SwiftRecipes installed yet. Open the starter project, and build and run for this simulator, which loads the app with the version 1 schema onto the simulator.

See forum comments
Cinema mode Download course materials from Github
Previous: Migrating Your Schema Next: Conclusion