Reputation: 90
I'm trying to inject my core data viewcontext into several view models, so I don't need to pass one big view model throughout the whole app.
I'm using the SwiftUI lifecycle, so the NSManagedObjectContext is generated here:
@main
struct Core_Data_VM_TestApp: App {
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
}
Following along this answer I didn't succeed, also after playing along with different initializers.
What I want to do is something like this, which isn't working ('Cannot use instance member 'viewContext' within property initializer; property initializers run before 'self' is available')
Content View
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@StateObject var itemVM = ItemViewModel(viewContext: viewContext)
(...)
Viewmodel:
class ItemViewModel: ObservableObject {
var viewContext: NSManagedObjectContext
init(viewContext: NSManagedObjectContext) {
self.viewContext = viewContext
}
}
Thanks for any help!
Upvotes: 0
Views: 1108
Reputation: 29309
Just get it from your controller. The variable in the ViewModel will look something like
var viewContext: NSManagedObjectContext = PersistenceController.shared.container.viewContext
There is no need to pass it in the init.
Also, as a best practice if several anything are using something you should create an object for that something and put the common code there.
All the ViewModels can reference this single object. It will make changing things and debugging a million times easier as you app grows.
Upvotes: 2
Reputation: 10422
One approach is to not instantiate the @StateObject
in the declaration, but in the view's init
method. Note that the StateObject struct that wraps the itemVM
property is stored as _itemVM
:
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@StateObject var itemVM: ItemViewModel
init() {
_itemVM = StateObject(wrappedValue: ItemViewModel(viewContext: viewContext))
}
// ...
}
Upvotes: 0