I'm testing the new SwiftData to see if I can use it on one of my apps. Specifically I'm trying to learn how to use the schema migrations.
I made a new project using Xcode 15 beta 4. I selected to use SwiftData and iCloud.
I ran the generated project and I added a couple of items to the screen.
Then, I wanted to make a schema migration, so I changed the Item model from:
@Model
final class Item {
var timestamp: Date
init(timestamp: Date) {
self.timestamp = timestamp
}
}
to also include a string title:
@Model
final class Item {
var timestamp: Date
var title: String
init(timestamp: Date, title: String) {
self.timestamp = timestamp
self.title = title
}
}
I also made some changes to the SwiftUI code to include an empty string when adding a new item, so it could compile:
let newItem = Item(timestamp: Date(), title: "")
And then I added a new file containing the migration, according to what I saw on the video sessions:
//
// SwiftDataMigrations.swift
// Test 1
//
// Created by Diego on 12/07/23.
//
import Foundation
import SwiftData
enum ItemSchemaV1: VersionedSchema {
static var versionIdentifier: String?
static var models: [any PersistentModel.Type] {
[Item.self]
}
@Model
final class Item {
var timestamp: Date
init(timestamp: Date) {
self.timestamp = timestamp
}
}
}
enum ItemSchemaV2: VersionedSchema {
static var versionIdentifier: String?
static var models: [any PersistentModel.Type] {
[Item.self]
}
@Model
final class Item {
var timestamp: Date
var title: String
init(timestamp: Date, title: String) {
self.timestamp = timestamp
self.title = title
}
}
}
enum ItemsMigrationPlan: SchemaMigrationPlan {
static var schemas: [any VersionedSchema.Type] {
[ItemSchemaV1.self, ItemSchemaV2.self]
}
static var stages: [MigrationStage] {
[migrateV1toV2]
}
static let migrateV1toV2 = MigrationStage.lightweight(fromVersion: ItemSchemaV1.self, toVersion: ItemSchemaV2.self)
}
After that, I specified the migrationPlan in the app:
//
// Test_1App.swift
// Test 1
//
// Created by Diego on 12/07/23.
//
import SwiftUI
import SwiftData
@main
struct Test_1App: App {
var container = try! ModelContainer(
for: Item.self,
migrationPlan: ItemsMigrationPlan.self
)
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(container)
}
}
And then I tried to run the app but it crashed on launch with this error:
SwiftData/ModelContext.swift:179: Fatal error: Container does not have any data stores
Does anyone have any idea about what I might be missing?
The only thing that didn't matched the videos was that when creating a ModelContainer, the code on the video showed var container = ModelContainer... but the compiler showed the error Call can throw, but errors cannot be thrown out of a property initializer, so I added the try!. Also, on the VersionedSchema, I had to add static var versionIdentifier: String?.
Other than that I have no idea.
Thanks in advance.