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
Value of Type 'Authdataresult' Has No Member 'Uid'
Using Tvposterimage in Tvuikit for Tvos 12
When Two Optionals Are Assigned to an If Let Statement, Which One Gets Unwrapped? Swift Language
How to Pass Arguments into a Function with Completion Swift
How to Pass Closure as a Parameter in Perform(Selector, Withobject)
Swift 2 Unrecognized Selector in Tapgesture
How to Generate a Random Unicode Character in Swift
How to Give Xib Cell Button Action in Homevc in Swift
Check If the Username Exist in Firebase
How to Use a Switch Statement with a Nested Enum
Use Huge Numbers in Apple Swift
Need Explaining on the Double Label Function Declaration
App Window on Top of All Windows Including Others App Windows
What Are 3 Items in a Swift Method Parameter For
Macos Playground: How Can Change the Background Color
Handle Single Click and Double Click While Updating the View