Home > Net >  How is possible implementing MVVM in Swift with an environment object containing the data and differ
How is possible implementing MVVM in Swift with an environment object containing the data and differ

Time:04-03

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:

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)
               }
    }
}
  • Related