I have an Entity called Lessons, which consists of:
@NSManaged public var timeMinutes: Double
@NSManaged public var id: UUID
@NSManaged public var lessonDescription: String
@NSManaged public var date: Dates
The 'date' attribute is linked with a one-to-many relationship to a separate 'Dates' entity, which consists of:
@NSManaged public var date: Date
I am now trying to display a graph that has the summed 'timeMinutes' by 'date'. This finalArray would have the following structure:
struct FinalArray {
let summedMinutes : Double
let date : Date
}
My code to generate (and display) this array looks as following:
import SwiftUI
import SwiftUICharts
struct Test: View {
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(fetchRequest: Lessons.allLessonsFetchRequest()) var lessons: FetchedResults<Lessons>
var finalArray = [FinalArray]()
init(){
let allKeys = Set<Date>(lessons{$0.date.date})
for key in allKeys {
let sum = lessons.filter({$0.date.date == key}).map({$0.timeMinutes}).reduce(0, +)
finalArray.append(FinalArray(summedMinutes:sum, date:key))
}
finalArray = finalArray.sorted(by: {$0.date < $1.date})
}
var body: some View {
VStack{
LineView(data: finalArray.map {$0.summedMinutes}, title: "This graph returns empty").padding()
LineView(data: lessons.map {$0.timeMinutes}, title: "This graph works").padding()
}
}
}
I get the following error, on the first line of init:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
Does anyone know how I can fix this? What is the reason for this?
If I do a ForEach on the Core Data within my view, it works OK:
var dateFormatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateStyle = .long
return formatter
}
ForEach(lessons.map {$0.date.date}, id: \.self) { item in
VStack{
Text("\(item, formatter: self.dateFormatter)")
Text(String(self.lessons.filter{$0.date.date == item}.map {$0.timeMinutes}.reduce(0, +)))
}
}
This code works, but it's not what I want, I want to display the summed 'timeMinutes' in an Array. Any ideas or workarounds would be super welcome!
The lessons
is fetched on view initial update, but on init
it is not defined yet, so trying to use it in there you've got a crash.
Here is possible approach:
@State private var finalArray = [FinalArray]()
var body: some View {
VStack{
LineView(data: finalArray.map {$0.summedMinutes}, title: "This graph returns empty").padding()
LineView(data: lessons.map {$0.timeMinutes}, title: "This graph works").padding()
}
.onAppear {
let allKeys = Set<Date>(lessons{$0.date.date})
for key in allKeys {
let sum = lessons.filter({$0.date.date == key}).map({$0.timeMinutes}).reduce(0, +)
finalArray.append(FinalArray(summedMinutes:sum, date:key))
}
finalArray = finalArray.sorted(by: {$0.date < $1.date})
}
}