Reputation: 3336
I'm creating a SwiftUI macOS app with a dynamic menu item list that will be created based on the user's data:
Here's how I'm trying to create the menu:
@main
struct MacOSApp: App {
@AppStorage("tagFilter") private var tagFilter: String = ""
@FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Tag.name, ascending: true)], animation: .default)
private var tags: FetchedResults<Tag>
var body: some Scene {
WindowGroup {
ContentView(menuBarActionsState: menuBarActionsState)
.environment(\.managedObjectContext, storageProvider.persistentContainer.viewContext)
}.commands {
CommandGroup(before: CommandGroupPlacement.toolbar) {
Picker("Filter by Tag", selection: $tagFilter) {
ForEach(tags, id: \.self) { tag in
Text(tag.name ?? "").tag(tag.id ?? "")
}
}
}
}
}
}
The problem is, I don't have a managedObjectContext
in the @main
app, as this is the starting point of the application. It is injected into the environment of the ContentView
, but the menu is created above that.
Because I don't have a managedObjectContext
, the following error happens at runtime:
Context in environment is not connected to a persistent store coordinator: <NSManagedObjectContext: 0x6000039a2700>
Can we access the managedObjectContext
in the @main
app level? Or can I inject a managedObjectContext
in my @FetchRequest
somehow, so I can use it in the @main
app to build the menu?
Upvotes: 0
Views: 69
Reputation: 30567
Break up your View data structs to be as small as possible based on the vars they use. It's called having a tight invalidation and should resolve the problem.
@main
struct MacOSApp: App {
var body: some Scene {
WindowGroup {
ContentView(menuBarActionsState: menuBarActionsState)
.environment(\.managedObjectContext, storageProvider.persistentContainer.viewContext)
}.commands {
CommandGroup(before: CommandGroupPlacement.toolbar) {
TagsView()
}
.environment(\.managedObjectContext, storageProvider.persistentContainer.viewContext)
}
}
}
struct TagsView: View {
@AppStorage("tagFilter") private var tagFilter: String = ""
@FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Tag.name, ascending: true)], animation: .default)
private var tags: FetchedResults<Tag>
var body: some View {
Picker("Filter by Tag", selection: $tagFilter) {
ForEach(tags, id: \.self) { tag in
Text(tag.name ?? "").tag(tag.id ?? "")
}
}
}
}
Upvotes: 2