How to define SwiftData models using the @Model macro
How to define SwiftData models using the @Model macro 관련
Updated for Xcode 15
You’ll use the @Model
macro with all your SwiftData model classes. It automatically makes your class load and store from SwiftData, adds support for observing changes, and also adds conformances for Hashable
, Identifiable
, Observable
, and PersistentModel
.
In a simple case, your code looks like this:
@Model
class Employee {
var name: String
var emailAddress: String
init(name: String, emailAddress: String) {
self.name = name
self.emailAddress = emailAddress
}
}
That now becomes the source of truth for this data model – the complete definition of the data structure for that one type.
Important
The @Model
macro requires your type be a class; it will not work on a struct.
Just marking the class with @Model
automatically converts its stored properties into getters and setters that read/write the underlying SwiftData information, but it’s even smarter than that:
- Whenever a SwiftUI view reads one of the properties of a SwiftData model object, it will automatically watch that property for changes so the view can be recreated as needed. If you previously used
@Published
and similar to annotate properties, that is not needed with SwiftData. - SwiftData quietly groups multiple changes together to save in one pass, so even if you do all sorts of inserting, deleting, and updating, they’ll be batched for maximum performance.
- Whenever one of these batches completes, SwiftData automatically saves all its outstanding changes, so your data is always kept safe.
- Any computed properties aren’t affected by the macro, and won’t be stored inside SwiftData persistent storage.
There are all sorts of ways to expand your models further. For example, we might say that every employee has a manager, like this:
@Model
class Employee {
var name: String
var emailAddress: String
var manager: Employee?
init(name: String, emailAddress: String, manager: Employee?) {
self.name = name
self.emailAddress = emailAddress
self.manager = manager
}
}
That introduces a one-to-one relationship: each manager has another manager, although it’s an optional Employee
because someone at the very top of a company won’t have a manager. Relationships are covered in more detail later.
Another way we can add to our models is to add special attributes to individual properties. For example, we could say that every employee must have a unique email address:
@Model
class Employee {
var name: String
@Attribute(.unique) var emailAddress: String
init(name: String, emailAddress: String) {
self.name = name
self.emailAddress = emailAddress
}
}
SwiftData will enforce this rule for us automatically, ensuring that no two users have the same email address.