Duck
Duck

Reputation: 35953

No ObservableObject of type XXX found just inside a notification observer

I have a class like this:

class GlobalVariables: ObservableObject {
  @Published var aaa = AAA()
  @Published var bbb = BBB()
  @Published var ccc = CCC()
}

When I want to access that, I add this to a view:

@EnvironmentObject var globalVariables : GlobalVariables

and that's it.

So, I did that to my view called MyView.

and I am happy. I can access globalVariables almost anywhere inside MyView.

But, and there is always a but, MyView contains this method:

  func initNotification() {
   let gv = globalVariables // 1
    NotificationCenter.default
      .addObserver(forName: .runOnDetectedObject,
                   object: nil,
                   queue: OperationQueue.main,
                   using: {notification in
                      globalVariables.aaa(object:myObj)) // 2
                   })
  }

//1 and //2 compile fine, but when I run, both lines crash with

Thread 1: Fatal error: No ObservableObject of type GlobalVariables found. A View.environmentObject(_:) for GlobalVariables may be missing as an ancestor of this view.

I have this on MyApp.swift

var body: some Scene {
    WindowGroup {
      ContentView()
        .environment(\.managedObjectContext, persistenceController.container.viewContext)
        .environmentObject(GlobalVariables())
    }
  }

The view I am having the problem is not ContentView()

Why?

Upvotes: 0

Views: 154

Answers (1)

lorem ipsum
lorem ipsum

Reputation: 29309

Without a Minimal Reproducible Example it is impossible to help you troubleshoot.

But, you have to pass the EnvironmentObject down.

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext
    @EnvironmentObject var globalVariables : GlobalVariables

    var body: some View {
        MyView().environmentObject(globalVariables)
    }
}

It usually only works for about 2-3 layers. If you go any deeper than that it is pretty buggy.

Upvotes: 1

Related Questions