This article mainly explains the relationships in SwiftData.
The relationship of SwiftData can be automatically inferred through the model structure you define. It can also be explicitly declared through the @ Relationship macro.
Generally speaking, an explicit declaration is only necessary when you do not want to use the default configuration. Usually, you don't need @ Relationship.
For example, the following example:
![]()
We defined a class for School and a class for Student, and used the School declaration property in Student; Declare an array using Student in School. From the above code, SwiftData can infer that:
However, these two are not coupled together, they are separate. If we create a student and set its school attribute, SwiftData does not understand how to add the student to the students array of that school, and it will not automatically infer that this relationship is bidirectional.
If we change Student to the following code:
![]()
The only change is that we declare school as an optional type, which means its value may be empty. This change is based on security considerations:
When we declare the school attribute as a non optional value, it means that the above situation is impossible and students must belong to a school. If the student's school attribute is not assigned, SwiftData will trigger a crash because we put it in an invalid state.
On the other hand, once we set the school attribute as optional, this danger disappears: deleting a student from the students array will only set their school attribute to nil, so there is no risk of crashing.
The rule here is simple: if the relationship can be safely inferred, SwiftData will automatically infer it.
Many times, this is not enough, we can use the @ Relationship macro on one of the two models to create explicit relationships that explicitly indicate connections. For example, we can change the Student class to make its school attribute look like this:@Relationship(inverse: \School.students) var school: School
This can be optional or non optional - there are no security restrictions here because you have accurately told SwiftData what you want.
Alternatively, we can modify the School class to have the following student attributes: @Relationship(inverse: \Student.school) var students: [Student]








