I have my preview canvas crashing because the environmentObject is not properly set. The app itself builds and run properly.
Error message.
app crashed due to missing environment of type: TaskModel. To resolve this add .environmentObject(TaskModel(...)) to the appropriate preview.
My View with the #Preview macro looks like this.
struct CopyTaskListScreen: View {
@EnvironmentObject private var taskModel: TaskModel
var body: some View {
NavigationStack {
List(taskModel.tasks.sorted(by: <), id: \.key) { task in
Text(task.value.title)
}
}
}
}
#Preview {
CopyTaskListScreen()
.environmentObject(TaskModel(//how to call TaskDataService here?))
}
My TaskModel looks the following. I inject the TaskDataService with the ITaskData protocol. The TaskDataService accepts all data adapters implementing the ITaskData protocol and hand it over to my TaskModel.
@MainActor
class TaskModel: ObservableObject {
@Published var tasks: [UUID: Task] = [:]
var data: TaskDataService
init(data: ITaskData) {
self.data = TaskDataService(data: data)
readTasks()
}
I tried to inject the environment in #Preview the same way I did it in @main. But with the same result. Preview canvas is crashing.
@main
struct mTaskApp: App {
var body: some Scene {
WindowGroup {
MainScreen()
.environmentObject(TaskModel(data: TaskDataService(data: RemindersDataAdapter())))
Normally your service would be an EnvironmentKey, e.g.
@Environment(\.taskDataService) var taskDataService
@EnvironmentObject private var taskModel: TaskModel
And would use it like this
.task {
await taskDataService.load(into: taskModel)
}
Or better (where results is State):
.task {
results = await taskDataService.load()
}
Then in preview it would be:
#Preview {
CopyTaskListScreen()
.environment(\.taskDataService, MockTaskDataService())
.environmentObject(TaskModel())
}
protocol TaskDataService{}
struct RealTaskDataService: TaskDataService{}
struct MockTaskDataService: TaskDataService{}