I'm trying to implement my app architecture loading in the app struct an object containing the data to be shared in all the views of the app through an environment object:
@main
struct SMT_testingApp: App {
@StateObject private var dataManager = DataManager()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(dataManager)
}
}
}
Here's the Datamanager class publishing the var containing the data:
class DataManager: ObservableObject {
@Published var SMTItemList: [SMTItem] = [SMTItem(id: UUID(), itemDesc: "", itemCreaDate: Date(), itemUpdDate: Date(), itemTags: [], linkedItemsUID: [])]
var urlFile: URL {
getDocumentsDirectory().appendingPathComponent("/SMT.json")
}
init() { loadData() }
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
func loadData() {
//...
After here the View that contain the instance of his view model:
struct ContentView: View {
@StateObject private var viewModel = ViewModel()
var body: some View {
List(viewModel.dataManager.SMTItemList) { item in
SMTItemView(item: item)
}
}
}
struct SMTItemView: View {
var item : SMTItem
var body: some View {
Text("Item desc: \(item.itemDesc)")
}
}
And finally, the view model that contains the environment object with the data.
extension ContentView {
class ViewModel: ObservableObject{
@EnvironmentObject var dataManager: DataManager
}
}
Now, the code is built correctly but at runtime I obtain this error in the content View:
What I'm doing wrong? Is correct implementing an architecture that way (one enviroment object with the data and many views/view models) ? Thanks
CodePudding user response:
@EnvironmentObject must be in view scope, not view model class. Like
struct ContentView: View {
@StateObject private var viewModel = ViewModel()
@EnvironmentObject var dataManager: DataManager // << here !!
var body: some View {
List(dataManager.SMTItemList) { item in
SMTItemView(item: item)
}
}
}