Swift Charts Won't Update a Variable Value

I am currently working on a project for the Swift Student Challenge. One part of the app is for visualizing goals with a chart created using Swift Charts. In the app, you log your progress for the goal and then it should show up in the chart. My issue is that the data is not showing after it has been logged. Here are some code snippets:

Code For Chart View

Chart {
                let currentDate = Date.now
                
                BarMark (
                    x: .value("Day", "Today"),
                    y: .value("Score", goalItem.getLogItemByDate(date: currentDate).score)
                )
            }
            .frame(maxHeight: 225)
            .padding()

GoalItem Data Object

public class GoalItem: Identifiable {
    public var id: String
    var name: String
    var description: String
    var logItems: [String: GoalLogItem]
    
    init(name: String, description: String) {
        self.id = UUID().uuidString
        self.name = name
        self.description = description
        self.logItems = [:]
    }
    
    func log(date: Date, score: Double, notes: String) {
        self.logItems[dateToDateString(date: date)] = GoalLogItem(date: date, score: score, notes: notes)
    }
    
    func getLogItemByDate(date: Date) -> GoalLogItem {
        let logItem = self.logItems[dateToDateString(date: date)]
        if logItem != nil {
            return logItem!
        } else {
            return GoalLogItem(isPlaceholder: true)
        }
    }
}

After logging something using the GoalItem.log method, why does it not show up in the chart? Are the variables not updated? If so, how would I get the variables to update?

Thanks

Answered by jcovin293 in 779738022

After reading a few code snippets, I have found the source of this issue. In my chart, I had this line of code: @State var goalItem: GoalItem, it should instead be @StateObject. After making that change, my code is now working normally.

So ChartView is a SwiftUI view ?

What is the State var or the Observable that is updated when you log something, so that the UI is updated ?

You should provide more code of Chart View.

Also; have a look at this TN: https://developer.apple.com/documentation/swiftui/migrating-from-the-observable-object-protocol-to-the-observable-macro

I have checked that because I am using an iOS playground I can't use the Observable macro as it seems to be unavailable in an iOS playground. Here is my full code for the SwiftUI view if this helps at all (P.S. I tried adding @State to goalItem but that didn't seem to do anything):

import Charts

enum ChartTimeFrame: String, CaseIterable, Identifiable {
    case week, month, sixMonth, year, all
    var id: Self { self }
}

struct GoalDetailView: View {
    @State var goalItem: GoalItem
    @State private var pickerTimeFrame: ChartTimeFrame = ChartTimeFrame.week
    @State private var showLogSheet: Bool = false
    @State var logScore: Double = 6.0
    @State var logNotes: String = ""
    @State var logDate: Date = Date.now
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        VStack {
            Picker("Timeframe", selection: $pickerTimeFrame) {
                Text("W").tag(ChartTimeFrame.week)
                Text("M").tag(ChartTimeFrame.month)
                Text("6M").tag(ChartTimeFrame.sixMonth)
                Text("Y").tag(ChartTimeFrame.year)
                Text("ALL").tag(ChartTimeFrame.all)
            }
            .pickerStyle(.segmented)
            .padding()
            
            Chart {
                let currentDate = Date.now
                
                BarMark (
                    x: .value("Day", "Today"),
                    y: .value("Score", goalItem.getLogItemByDate(date: currentDate).score)
                )
            }
            .frame(maxHeight: 225)
            .padding()
            
            Spacer()
            
            List {
                NavigationLink(destination: GoalDataList(goalItem: goalItem)) {
                    Text("Show All Data")
                }
                .navigationTitle(goalItem.name)
                .toolbar {
                    Button("Log") {
                        showLogSheet.toggle()
                    }
                    .sheet(isPresented: $showLogSheet) {
                        // goal log sheet code
                        GoalLogSheet(goalItem: goalItem)
                    }
                }
            }
            .scrollDisabled(true)
        }
    }
}

Thanks again

No, sorry for the confusion. The issue isn't fixed now. I was just stating that when I copied my code over into my post, I forgot to copy the import SwiftUI statement so I was clarifying that that wasn't the problem. This may be an issue with iOS Playgrounds but I am unsure. Thanks for your help.

I have done a little bug testing and it seems to be an issue with updating the view. If I add data to the chart via the app and then exit the view and reenter, the information will then show. How would I go about updating the view after new information has been added?

Accepted Answer

After reading a few code snippets, I have found the source of this issue. In my chart, I had this line of code: @State var goalItem: GoalItem, it should instead be @StateObject. After making that change, my code is now working normally.

Swift Charts Won't Update a Variable Value
 
 
Q