-
Model your schema with SwiftData
Learn how to use schema macros and migration plans with SwiftData to build more complex features for your app. We'll show you how to fine-tune your persistence with @Attribute and @Relationship options. Learn how to exclude properties from your data model with @Transient and migrate from one version of your schema to the next with ease.
To get the most out of this session, we recommend first watching "Meet SwiftData" and "Build an app with SwiftData" from WWDC23.Capítulos
- 0:00 - Intro
- 1:41 - Utilizing schema macros
- 5:30 - Evolving schemas
- 8:56 - Wrap-up
Recursos
Vídeos relacionados
WWDC23
-
Buscar neste vídeo...
-
-
0:56 - Original Trip model
import SwiftUI import SwiftData @Model final class Trip { var name: String var destination: String var start_date: Date var end_date: Date var bucketList: [BucketListItem]? = [] var livingAccommodation: LivingAccommodation? } -
1:50 - Adding a unique attribute
@Model final class Trip { @Attribute(.unique) var name: String var destination: String var start_date: Date var end_date: Date var bucketList: [BucketListItem]? = [] var livingAccommodation: LivingAccommodation? } -
2:48 - Specifying original property names
@Model final class Trip { @Attribute(.unique) var name: String var destination: String @Attribute(originalName: "start_date") var startDate: Date @Attribute(originalName: "end_date") var endDate: Date var bucketList: [BucketListItem]? = [] var livingAccommodation: LivingAccommodation? } -
4:00 - Cascading delete rule
@Model final class Trip { @Attribute(.unique) var name: String var destination: String @Attribute(originalName: "start_date") var startDate: Date @Attribute(originalName: "end_date") var endDate: Date @Relationship(.cascade) var bucketList: [BucketListItem]? = [] @Relationship(.cascade) var livingAccommodation: LivingAccommodation? } -
4:54 - Transient properties
@Model final class Trip { @Attribute(.unique) var name: String var destination: String @Attribute(originalName: "start_date") var startDate: Date @Attribute(originalName: "end_date") var endDate: Date @Relationship(.cascade) var bucketList: [BucketListItem]? = [] @Relationship(.cascade) var livingAccommodation: LivingAccommodation? @Transient var tripViews: Int = 0 } -
7:12 - Defining versioned schemas
enum SampleTripsSchemaV1: VersionedSchema { static var models: [any PersistentModel.Type] { [Trip.self, BucketListItem.self, LivingAccommodation.self] } @Model final class Trip { var name: String var destination: String var start_date: Date var end_date: Date var bucketList: [BucketListItem]? = [] var livingAccommodation: LivingAccommodation? } // Define the other models in this version... } enum SampleTripsSchemaV2: VersionedSchema { static var models: [any PersistentModel.Type] { [Trip.self, BucketListItem.self, LivingAccommodation.self] } @Model final class Trip { @Attribute(.unique) var name: String var destination: String var start_date: Date var end_date: Date var bucketList: [BucketListItem]? = [] var livingAccommodation: LivingAccommodation? } // Define the other models in this version... } enum SampleTripsSchemaV3: VersionedSchema { static var models: [any PersistentModel.Type] { [Trip.self, BucketListItem.self, LivingAccommodation.self] } @Model final class Trip { @Attribute(.unique) var name: String var destination: String @Attribute(originalName: "start_date") var startDate: Date @Attribute(originalName: "end_date") var endDate: Date var bucketList: [BucketListItem]? = [] var livingAccommodation: LivingAccommodation? } // Define the other models in this version... } -
7:49 - Implementing a SchemaMigrationPlan
enum SampleTripsMigrationPlan: SchemaMigrationPlan { static var schemas: [any VersionedSchema.Type] { [SampleTripsSchemaV1.self, SampleTripsSchemaV2.self, SampleTripsSchemaV3.self] } static var stages: [MigrationStage] { [migrateV1toV2, migrateV2toV3] } static let migrateV1toV2 = MigrationStage.custom( fromVersion: SampleTripsSchemaV1.self, toVersion: SampleTripsSchemaV2.self, willMigrate: { context in let trips = try? context.fetch(FetchDescriptor<SampleTripsSchemaV1.Trip>()) // De-duplicate Trip instances here... try? context.save() }, didMigrate: nil ) static let migrateV2toV3 = MigrationStage.lightweight( fromVersion: SampleTripsSchemaV2.self, toVersion: SampleTripsSchemaV3.self ) } -
8:40 - Configuring the migration plan
struct TripsApp: App { let container = ModelContainer( for: Trip.self, migrationPlan: SampleTripsMigrationPlan.self ) var body: some Scene { WindowGroup { ContentView() } .modelContainer(container) } }
-