@ComputedProperty vs copying values SwiftData AppEntity

I'm setting up App Entities for my SwiftData models and I'm not sure about the best way to reference SwiftData model properties in the AppEntity.

I have a SwiftData model with many properties:

@Model
final class Contact {
    @Attribute(.unique) var id: UUID = UUID()
    var name: String
    var phoneNumber: String
    var email: String
    var website: URL?
    var birthday: Date?
    var notes: String
    // ... many more properties
}

I want to expose these properties on my AppEntity so they're available for system features, such as giving Apple Intelligence more context about on-screen content.

struct ContactEntity: AppEntity {
    var id: UUID
    
    @Property(title: "Name")
    var name: String
    
    @Property(title: "Phone")
    var phoneNumber: String
    
    @Property(title: "Email")
    var email: String
    
    // ... all the other properties
}

I couldn't find guidance in the documentation for this specific situation. I've considered two approaches:

  • Add @Property variables to the AppEntity for each SwiftData model property and copy all values from the SwiftData model to the AppEntity in the AppEntity initializer — but I recall this being discouraged in previous WWDC sessions since it duplicates data and can become stale

  • Use @ComputedProperty to fetch the model and access the single properties — this seems like an alternative, but fetching the entire model just to access individual properties doesn't feel right

What is the recommended approach when SwiftData is the data source? Thank you!

Answered by DTS Engineer in 873248022

A @Property variable is computed when the app entity (AppEntity) is initialized, while a @ComputedProperty variable is computed when the entity is returned. So yes, the SwiftData model can become stale if it changes after the app entity is initialized.

Assuming that you have a data controller that manages your SwiftData models, I'd think that you can make the SwiftData model associated with the app entity up to date, so that the getters of your @ComputedProperty variables can return the value directly (without doing a fetch).

To ensure the SwiftData model is up to date, you might need to observe the notifications triggered by a store change (basically NSManagedObjectContextObjectsDidChange and .NSPersistentStoreRemoteChange, assuming you are using DefaultStore), check if the change is relevant, and re-fetch the data as needed. If you need more discussion on this topic, feel free to follow up with more details about how your SwiftData store may change,

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

A @Property variable is computed when the app entity (AppEntity) is initialized, while a @ComputedProperty variable is computed when the entity is returned. So yes, the SwiftData model can become stale if it changes after the app entity is initialized.

Assuming that you have a data controller that manages your SwiftData models, I'd think that you can make the SwiftData model associated with the app entity up to date, so that the getters of your @ComputedProperty variables can return the value directly (without doing a fetch).

To ensure the SwiftData model is up to date, you might need to observe the notifications triggered by a store change (basically NSManagedObjectContextObjectsDidChange and .NSPersistentStoreRemoteChange, assuming you are using DefaultStore), check if the change is relevant, and re-fetch the data as needed. If you need more discussion on this topic, feel free to follow up with more details about how your SwiftData store may change,

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

@ComputedProperty vs copying values SwiftData AppEntity
 
 
Q