I have a StateController class:
import Foundation
import Combine
class StateController: ObservableObject {
// Array of subjects loaded in init() with StorageController
@Published var subjects: [Subject]
private let storageController = StorageController()
init() {
self.subjects = storageController.fetchData()
}
// MARK: - Computed properties
// Array with all tasks from subjects, computed property
var allTasks: [Task] {
var all: [Task] = []
for subject in subjects {
all += subject.tasks
}
print("Computed property updated!")
return all
}
var numberofCompletedTasks: Int {
return subjects.map({$0.tasks.map({$0.isCompleted == true})}).count
}
var numberOfHighPriorityTasks: Int {
return subjects.map({$0.tasks.map({$0.priority == 1})}).count
}
var numberOfMediumPriorityTasks: Int {
return subjects.map({$0.tasks.map({$0.priority == 2})}).count
}
var numberOfLowPriorityTasks: Int {
return subjects.map({$0.tasks.map({$0.priority == 3})}).count
}
}
And a SwiftUI view:
import SwiftUI
struct SmartList: View {
// MARK: - Properties
let title: String
@EnvironmentObject private var stateController: StateController
// MARK: - View body
var body: some View {
List(stateController.allTasks, id: \.taskID) { task in
TaskView(task: task)
.environmentObject(self.stateController)
}.listStyle(InsetGroupedListStyle())
.navigationTitle(LocalizedStringKey(title))
}
}
When I update "Task" objects inside "subjects" @Published array, for example checking them as complete, SwiftUI should automatically update the view because computed properties are derived from @Published property of an ObservableObject (declared as @EnvironmentObject inside view) but it doesn't work.
How can I bind my SwiftUI view to computed properties derived from a @Published property??