Android

Relationship in SwiftData

2025-10-29

This article mainly explains the relationships in SwiftData.


Automatic inference

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:

//img.enjoy4fun.com/news_icon/d40qiaddm8bc72v8svk0.png

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:

  • Every school can have many students
  • Each student belongs to only one school

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:

//img.enjoy4fun.com/news_icon/d40qimb8hlms72omov7g.png

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:

  • If there is a relationship between the student and the school, setting the student's school attribute should add it to the school's student list or remove it from the school's student list
  • Similarly, adding or deleting students from the school's student list should also synchronize the modification of their school attributes
  • So, what happens if you remove a student from one school instead of adding them to another?

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.


Explicit declaration

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]


more stories
See more