SwiftUI - how to get @EnvironmentObject data inside @ObservableObject

Viewed 1442

Is it possible to use a @EnvironmentObject inside an ObservableObject?

It is giving me an error:

Fatal error: No ObservableObject of type EntryViewModel found. A View.environmentObject(_:) for EntryViewModel may be missing as an ancestor of this view.: file SwiftUI, line 0

I know the @EnvironmentObject is good because I use it other places.

If not, how can I get the information?

class ResultsViewModel: ObservableObject {
    @EnvironmentObject var entry: EntryViewModel
    ...
}

Thank you.

2 Answers

Is it possible to use a @EnvironmentObject inside an ObservableObject?

No, it is not. @EnvironmentObject can be used in View only.

If not, how can I get the information?

A possible solution is to pass it in init:

class ResultsViewModel: ObservableObject {
    var entry: EntryViewModel

    init(entry: EntryViewModel) {
        self.entry = entry
    }
}

Another solution may be to use a singleton or (maybe the best) dependency injection.

You need to go via DynamicProperty making use of its update func, e.g.

class MyObject: ObservableObject {
    var context: NSManagedObjectContext? {
        didSet {
            if oldValue != context {
                // do something
            }
        }
    }
}

struct MyProperty: DynamicProperty {
    @Environment(\.managedObjectContext) private var viewContext
    @StateObject var object = MyObject()

    // update is called before body in the View containing this property
    func update() {
        // environment vars now are valid
        object.context = viewContext    
    }
}

struct MyView {
    var myProperty = MyProperty()

    var body: some View {
    }
}
Related