Where to create View Model (or observed object) in SwiftUI?

In SwiftUI, is it a good idea to create a view model (or observed object) in a View? For example, if I write a code like this:

struct AView: View {

    ...

    public var body: some View {
        ...
        ForEach(...) {
            ...
            otherView
        }
    }

    private var otherView: some View {
        let model = OtherViewModel()
         return OtherView().environmentObject(model)
    }
}

I guess this will re-create OtherViewModel every time AView is refreshed, so maybe this is not a good approach after all?

I thought about creating it in the constructor of AView, but if otherView is created multiple times using ForEach like the example above, it's difficult to know ahead of time how many of these models I need to create.

Any suggestion is highly appreciated!

Thanks,

Replies

I would do it in main app struct like this and pass it into your main view.

import SwiftUI
@main
struct MyApp: App {        

  private let viewModel = MyAppViewModel()   
     
  var body: some Scene {        
    WindowGroup {            
      MyAppView(viewModel: viewModel)           
    }
  }
}

Thanks, but what about the case in my example, where we need to create this view multiple times in a ForEach statement?

Maybe try something like this.

struct AView: View {
    @ObservedObject var viewModel: MyAppViewModel
    ...

    public var body: some View {
        ...
        ForEach(...) {
            ...
            OtherView(vm: viewModel)
        }
    }
}

struct OtherView: View {
    @ObservedObject var vm: MyAppViewModel
    var body: some View {
    ...
    }
}

Your ViewModel should be a class so when you pass it around you are just passing the same instance of the class around rather than creating new instance of it each time.