Swiftui @Environmentobject Error: May Be Missing as an Ancestor of This View -- Accessing Object in the Init()

SwiftUI @EnvironmentObject error: may be missing as an ancestor of this view -- accessing object in the init()

The answer is that an Environment Object apparently cannot be accessed in an init() function. However, an ObservedObject can be. So I changed the code to this and it works. To make it easy I turned TState into a singleton that I could access anywhere. This could probably replace the use of @EnvironmentObject in many situations.

struct TEditorView: View {
@ObservedObject private var tState = TState.shared
//@EnvironmentObject private var tState: TState

@State var name = ""

init() {
self._name = State(initialValue: tState.name)
}

var body: some View {
...
}
}

SwiftUI @EnvironmentObject error: may be missing as an ancestor of this view

The whole issue is very easy to fix just add self.networkManager @ EarthQuakeList.swift

.sheet(isPresented: $showEditPage) { 
return EditPage().environmentObject(self.networkManager)

I got the reason and inspired from article:
https://github.com/peterfriese/Swift-EnvironmentObject-Demo

A View.environmentObject(_:) may be missing as an ancestor of this view - but not always…

The reason your problem is intermittent, is probably because the PurchaseManager init()
could finish
before all the data is setup properly, due to the "delays" of the
async functions in init(). So sometimes the data will be available
when the View wants it, and sometimes it will not be there and crash your app.

You could try the following approach that includes @atultw advice of using
StateObject.

import SwiftUI

@main
struct TestApp: App {
@StateObject var purchaseManager = PurchaseManager() // <-- here

var body: some Scene {
WindowGroup {
MainView()
.onAppear {
purchaseManager.startMeUp() // <-- here
}
.environmentObject(purchaseManager)
}
}
}

struct MainView: View {
@EnvironmentObject var purchaseManager: PurchaseManager

var body: some View {
Text("testing")
List {
ForEach(purchaseManager.offerings, id: \.self) { offer in
Text(offer)
}
}
}
}

public class PurchaseManager: ObservableObject {
@Published var offerings: [String] = []

// -- here --
func startMeUp() {
// setupRevenueCat()
fetchOfferings()
// refreshPurchaserInfo()
}

func fetchOfferings() {
DispatchQueue.main.asyncAfter(deadline: .now()+2) {
self.offerings = ["offer 1","offer 2","offer 3","offer 4"]
}
}
}

Error when trying to open my Preview in Swiftui

Your NavigationBar view needs to receive an @EnvironmentObject, also from the preview.

Inside your NavigationBar_Previews, add one more modifier to the view, like this:

NavigationBar()
.environmentObject(AppInformation()) // Add all initialisers necessary
// to create the instance of AppInformation()

No ObservableObject of type TypeName found. A View.environmentObject(_:) for TypeName may be missing as an ancestor of this view

You need to inject the @EnvironmentObject into each environment (remember that each .sheet or .fullScreenCover creates a new environment):

Button("Open Child View A"){
viewModel.isPresented.toggle()
}
.fullScreenCover(isPresented: $viewModel.isPresented) {
ChildViewA(isPresented: $viewModel.isPresented)
.environmentObject(EnvObj()) // inject here
}

Note: the EnvironmentObject must be created first. You can't access it by @EnvironmentObject var envObj: EnvObj if it isn't created and injected in the first place.

Also, you don't really need to create your dependencies directly in the fullScreenCover closure. You can put them at the root level and inject accordingly.

No ObservableObject of type CarouselViewModel found. A View.environmentObject(_:) for CarouselViewModel may be missing as an ancestor of this view

Wherever you instantiate the Home view, you have to add an .environmentObject modifier that passes an instance of CarouselViewModel to it.

I don't know what your exact code looks like (or what CarouselViewModel takes as parameters), but it'll look something like:

//somewhere in the parent view:
@StateObject private var model = CarouselViewModel() //if iOS 13, use @ObservedObject

//where you instantiate `Home`:
Home().environmentObject(model)

Note that this will also be an error if you try to use Home in a SwiftUI Preview and it doesn't have this .environmentObject code.

Why Is EnvironmentObject Not Working in SwiftUI Project?

in your app you have:

ContentView().environmentObject(marketplaceViewModel)

so in "ContentView" you should have as the first line:

@EnvironmentObject var marketplaceViewModel: MarketplaceViewModel

Note in "ContentView" you have, "@EnvironmentObject var authSession: AuthSession"
but this is not passed in from your App.

Edit: test passing "marketplaceViewModel", using this limited setup.

class MarketplaceViewModel: ObservableObject {
...
let showMiki = "here is Miki Mouse"
...
}

and

struct MarketplaceView: View {
@EnvironmentObject var marketplaceViewModel: MarketplaceViewModel

var body: some View {
// ERROR NOT HERE
Text(marketplaceViewModel.showMiki)
// Text(self.marketplaceViewModel.listingRowViewModels[1].listing.title)
}
}


Related Topics



Leave a reply



Submit