@EnviromentObject
is passed down when the body is called, so it doesn't yet exist during the initialization phase of the View struct. Ok, that is clear. The question is, how do you solve the following problem?
struct MyCollectionScreen: View {
// Enviroment
@EnvironmentObject var viewContext: NSManagedObjectContext
// Internal dependencies
@ObservedObject private var provider: CoreDataProvider
init() {
provider = CoreDataProvider(viewContext: viewContext)
}
}
The previous doesn't compile and throws the error:
'self' used before all stored properties are initialized.
That is because I am trying to use the @EnviromentObject
object before it is actually set.
For this, I am trying a couple of things but I am not super happy with any of them
1. Initialize my provider
after the init()
method
struct MyCollectionScreen: View {
// Enviroment
@EnvironmentObject var viewContext: NSManagedObjectContext
// Internal dependencies
@ObservedObject private var provider: CoreDataProvider
var body: some View {
}.onAppear {
loadProviders()
}
mutating func loadProviders() {
provider = CoreDataProvider(viewContext: viewContext)
}
}
but that, doesn't compile either and you get the following error within the onAppear
block:
Cannot use mutating member on immutable value: 'self' is immutable
2. Pass the viewContext in the init method and forget about Environment objects:
This second solution works, but I don't like having to pass the viewContext
to most of my views in the init methods, I kind of liked the Environment object idea.
struct MyCollectionScreen: View {
// Internal dependencies
@ObservedObject private var provider: CoreDataProvider
init(viewContext: NSManagedObjectContext) {
provider = CoreDataProvider(viewContext: viewContext)
}
}