I passed the environmentObject appSettings into my view successfully. I can use it to modify my font and the picker in my View. But if I try to access an environmentObject published variable in the view init() it crashes with:
Thread 1: Fatal error: No ObservableObject of type AppSettings found.
A View.environmentObject(_:) for AppSettings may be missing as an ancestor of this view.
Are there special rules about using an environmentObject in a custom SwiftUI View initializer?
Here's the start of my view code. The environmentObject is appSettings. If I comment out line 2 in my initializer and uncomment line 3 the app works. Note that I use "appSettings.interfaces" successfully later in my Picker.
struct CaptureFilterView: View {
@State var etherCapture: EtherCapture? = nil
@EnvironmentObject var appSettings: AppSettings
@Binding var frames: [Frame]
@State var captureFilter: String = ""
@State var error: String = ""
@State var numberPackets = 10
@State var interface: String = ""
init(frames: Binding<[Frame]>) {
self._frames = frames
self.interface = appSettings.interfaces.first ?? "en0" //CRASH HERE
//self.interface = "en0" //uncomment this and comment line above to make app "work"
}
var body: some View {
HStack() {
...
Picker(selection: $interface, label: Text("")) {
ForEach(appSettings.interfaces, id: \.self) { interfaceName in
Text(interfaceName).tag(interfaceName)
}
}
Here's where I create my top-level content view in my AppDelegate.swift
let contentView = ContentView(showCapture: true).environmentObject(appSettings)
And just to be sure I also pass on the environmentObject when creating my CaptureFilterView in my top level ContentView. This is not necessary and does not change the behavior.
if showCapture { CaptureFilterView(frames: self.$frames).environmentObject(appSettings) }
For reference here is the top of my appSettings:
class AppSettings: ObservableObject {
@Published var font: Font
@Published var interfaces: [String]
SwiftUI EnvironmentObject not available in View initializer?
Yes, SwiftUI EnvironmentObject not available in View initializer. Why? It is simple - it is injected after object initialiazation.
Let's consider how it is done on example of above ContentView
:
let contentView = ContentView(showCapture: true).environmentObject(appSettings)
so what's going on here? Here
let newInstance = ContentView.init(showCapture: true)
func environmentObject()
on newInstance
injected appSetting
propertylet contentView = newInstance.environmentObject(appSettings)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With