title: SwiftUI and MVVM - Communication between model and view model
body: <p>I've been experimenting with the MVVM model that's used in <code>SwiftUI</code> and there are some things I don't quite get yet.</p>
  
  <p><code>SwiftUI</code> uses <code>@ObservableObject</code>/<code>@ObservedObject</code> to detect changes in a view model that trigger a recalculation of the <code>body</code> property to update the view.</p>
  
  <p>In the MVVM model, that's the communication between the view and the view model. What I don't quite understand is how the model and the view model communicate.</p>
  
  <p>When the model changes, how is the view model supposed to know that? I thought about manually using the new <code>Combine</code> framework to create publishers inside the model that the view model can subscribe to.</p>
  
  <p>However, I created a simple example that makes this approach pretty tedious, I think. There's a model called <code>Game</code> that holds an array of <code>Game.Character</code> objects. A character has a <code>strength</code> property that can change.</p>
  
  <p>So what if a view model changes that <code>strength</code> property of a character? To detect that change, the model would have to subscribe to every single character that the game has (among possibly many other things). Isn't that a little too much? Or is it normal to have many publishers and subscribers?</p>
  
  <p>Or is my example not properly following MVVM? Should my view model not have the actual model <code>game</code> as property? If so, what would be a better way?</p>
  
  <pre class="lang-swift prettyprint-override"><code>// My Model
  class Game {
  
    class Character {
      let name: String
      var strength: Int
      init(name: String, strength: Int) {
        self.name = name
        self.strength = strength
      }
    }
  
    var characters: [Character]
  
    init(characters: [Character]) {
      self.characters = characters
    }
  }
  
  // ...
  
  // My view model
  class ViewModel: ObservableObject {
    let objectWillChange = PassthroughSubject&lt;ViewModel, Never&gt;()
    let game: Game
  
    init(game: Game) {
      self.game = game
    }
  
    public func changeCharacter() {
       self.game.characters[0].strength += 20
    }
  }
  
  // Now I create a demo instance of the model Game.
  let bob = Game.Character(name: "Bob", strength: 10)
  let alice = Game.Character(name: "Alice", strength: 42)
  let game = Game(characters: [bob, alice])
  
  // ..
  
  // Then for one of my views, I initialize its view model like this:
  MyView(viewModel: ViewModel(game: game))
  
  // When I now make changes to a character, e.g. by calling the ViewModel's method "changeCharacter()", how do I trigger the view (and every other active view that displays the character) to redraw?
  </code></pre>
  
  <p>I hope it's clear what I mean. It's difficult to explain because it is confusing</p>
  
  <p>Thanks!</p>