Problems with the keyword "some" with the Swift Charts framework

75 views Asked by At

I'm really new to Swift, and am making a simple app to track pellets eaten by my pet axolotl Miyamoto. I am trying to represent the pellet count visually using the Swift Charts Framework. However, I can't quite figure out how to solve this error that I am getting.

Property definition has inferred type 'State<Chart>', involving the 'some' return type of another declaration`

I get it whenever the ForEach loop is present, even though my code is quite simillar to this example. Removing the ForEach loop lets the code build and the build it works fine. I have done some reading on this and some is used when declaring a function, but I have no references to some in my ForEach loop. I have read this post, but no answers there seem to be relevant to my problem. I have done a lot of googling about this but there is still no solution that works. Here are the relevant parts of my code:


...

struct PelletArr: Identifiable {
    
    var pelletdata: Array<String>
    
    let id: Int = 987654321 // just put some number here to stop errors
}

......

struct ContentView: View {
    
    ......
    
    @State var charliechart: Chart = Chart {
        var pelletarrarr: Array<PelletArr> = []
        var _ = pelletstor.stor.forEach { item in
            pelletarrarr.append(PelletArr(pelletdata: item))
        }
        ForEach(pelletarrarr, id: \.pelletdata[0]) { pelletd in
            LineMark(
                x: .value("Date", DateString().dateNumber(dateStr: pelletd.pelletdata[0])),
                y: .value("Pellet Count", pelletd.pelletdata.count),
                series: .value("Axolotl", "A")
            )
            .foregroundStyle(.green)
        }
        RuleMark(
            y: .value("Fixed", 10)
        )
    }

    ......

}

NOTES:

  • PelletArr is a wrapper of the actual array, which is stored in the property pelletdata
  • ...... indicates code I deemed irrelevent
  • The formatting of the data storage is Array<Array<String>>, here is a small example:
[
["1/1/2003", "", "", "", ""]
     ^        ^   ^   ^   ^
  the date    these are all
 (Australia   blank strings,
   format)     1 equals 1 
                 pellet
]
  • The data is parsed from strings, which is stored in the Swift 'defaults'.
1

There are 1 answers

0
workingdog support Ukraine On BEST ANSWER

Since you are very new to SwiftUI, try this example code using a simple Chart{...} call inside the view body. The data is represented as an array of struct Pellet, that you load when the View appears.

Read more about how to make charts here: Charts

Also read about using @State in SwiftUI.

struct Pellet: Identifiable {
    let id = UUID()
    var name: String
    var type: String
    var count: Int
    var date: Date
}

struct ContentView: View {
    @State private var pellets: [Pellet] = []
    
    var body: some View {
        Chart {
            ForEach(pellets) { pellet in
                LineMark(
                    x: .value("Date", pellet.date),
                    y: .value("Pellet Count", pellet.count),
                    series: .value("Axolotl", "A")
                )
                .foregroundStyle(.green)
            }
            RuleMark(y: .value("Fixed", 10))
        }
        .chartForegroundStyleScale(["Axolotl" : Color.green])
        .onAppear {
            getData()
        }
    }
    
    func getData() {
        // random data for testing
        var day = 0
        for _ in 0..<10 {
            let count = Int.random(in: 0..<100)
            let temp = String(UUID().uuidString.prefix(5))
            let date = Date().addingTimeInterval(TimeInterval(60*60*24*day))
            pellets.append(Pellet(name: temp, type: temp, count: count, date: date))
            day += 1
        }
    }
}

Re your last comment,The data is parsed from strings, which is stored in the Swift 'defaults'. Don't store this kind of data in the UserDefaults, it is only meant to be used for small bits of setting data.

EDIT-1

If you really want to have a separate variable for your charliechart, then use this example code:

struct ContentView: View {
    @State private var pellets: [Pellet] = []
    
    @ViewBuilder private var charliechart: some View {
        Chart {
            ForEach(pellets) { pellet in
                LineMark(
                    x: .value("Date", pellet.date),
                    y: .value("Pellet Count", pellet.count),
                    series: .value("Axolotl", "A")
                )
                .foregroundStyle(.green)
            }
            RuleMark(y: .value("Fixed", 10))
        }
        .chartForegroundStyleScale(["Axolotl" : Color.green])
    }
    
    var body: some View {
        charliechart
            .onAppear {
                getData()
            }
    }
    
    func getData() {
        // random data for testing
        var day = 0
        for _ in 0..<10 {
            let count = Int.random(in: 0..<100)
            let temp = String(UUID().uuidString.prefix(5))
            let date = Date().addingTimeInterval(TimeInterval(60*60*24*day))
            pellets.append(Pellet(name: temp, type: temp, count: count, date: date))
            day += 1
        }
    }
}