Home > Enterprise >  Share ViewModel in Swiftui
Share ViewModel in Swiftui

Time:06-03

Disclaimer:I'm an Android developer but had to delve into a bit of Swift for a KMM project.

I have a ViewModel set up like so:

class MyViewModel:ObservableObject { 
...
var items Array = [Item]()
//the above array gets populated later on. Tried setting it as a state variable to be observed but for some reason the values never got updated 
...
}

I have already been able to access some other variables of MyViewModel from my Content View (which is the file it is located in but outside the struct's scope) like so:

struct ContentView: View {
@ObservedObject private (set) var viewmodel: MyViewModel 

var body: some View {...}
...
}

However, when I try to access the MyViewModel variables from another struct with a similar setup contained in another file like so:

struct TestView {     
        @ObservedObject private var viewmodel = MyViewModel() 
        var body: some View {        
            var cartItems = viewmodel.itemsArray     
        }
    }

, XCode shows the Cannot find type 'MyViewModel' in scope

Is there a way a ViewModel can be shared across multiple views on swift like it's done in Android/Kotlin?

CodePudding user response:

Check your variable's name in MyViewModel & remove the space. Publish that variable so it can update the view:

@Published var itemsArray = [Item]()

Also don't add variables to your View body, it should only contains element relevant to View.

So remove var cartItems = viewmodel.itemsArray & instead use viewmodel.itemsArray directly. You don't need a new variable.

Note: If your app is iOS 14 substitute @ObservedObject for @StateObject.

CodePudding user response:

I think it might work

final class ViewModel: ObservableObject {
  @Published var items = [Item]()
}

@Published modifier will notify body property if some changes happens.

Then if you want to share your ViewModel, you have to create "source of truth" Some one must own instance.

    struct ContentView: View {
      @StateObject var viewModel = ViewModel()
      
      var body: some View {...}
  }

Here @StateObject create new instance of ViewModel and you can share it.

struct TestView {     
        @ObservedObject var viewModel: ViewModel() 
        var body: some View {
        }
    }

@ObservedObject expects to receive ViewModel instance from elsewhere

CodePudding user response:

class MyViewModel:ObservableObject { 
...
@Published var items = [Item]()


struct ContentView: View {
@ObservedObject private var viewmodel = MyViewModel()
  • Related