skip to Main Content

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?

EDIT: Just realised that the ViewModel is contained within extension ContentView {} as it makes use of some enums within the extension.
Is there a way to access the variables as it is or do I have to change my code structure? How does this work in swift?

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search