Search code examples
iosswiftswiftuiswiftdata

Use SwiftData @Model and ObservableObject/@Published in the same class?


import SwiftData

@Model
final class PracticeData: ObservableObject, Codable {
    var score: Int
    var results: [PracticeResult]
    @Published var latestResult: Bool? //Error Property wrapper cannot be applied to a computed property
    var trend: Float

Im new to swift so Im kinda stuck. I have a view that is in a sheet that adds a new result to results (and overrides latestResult). When I close the sheet, the variable is displayed in the underlying view but is not updated. I need to go back to another view and come back to see the change. How do I use published and @Model at the same time? And if not possible, how do I update the view after so that it is updated with the new value of latestResult?

EDIT:

import SwiftData

@Model
final class PracticeData: Codable {
    public var score: Int
    var results: [PracticeResult]
    var latestResult: Bool?
    var trend: Float
var body: some View {
        List {
            Section {
                ForEach(lesson.vocab) { vocab in
                    var practiceData: PracticeData = vocab.practiceData
                    var score: Int = practiceData.score
                    ...
                    Text(String(score))
                    Button("addToScore", action: {
                                score += 1
                    })
                }

Solution

  • As other commenters said, @Model also makes your class Observable, just like @Observable. You should not use ObservableObject - your class is already Observable.

    Your mistake in the last code snippet is how you update the score.

    score += 1
    

    is just updating the local Int variable score. That doesn't call the setter of PracticeData.score (in which there is some code related to observation, added by @Model), and so the views don't observe the change.

    You should instead do:

    practiceData.score += 1