title: Swift Combine: turn a publisher into a read-only CurrentValueSubject
body: <p>Sometimes my viewmodel uses a <code>@Published</code> property or a <code>PassthroughSubject</code>, but I don't want this to be writeable to the outside world. Easy enough, turn it into a public <code>AnyPublisher</code> and keep the writable one private, like this:</p>
  
  <pre class="lang-swift prettyprint-override"><code>class ViewModel {
    @Published private var _models = ["hello", "world"]
  
    var models: AnyPublisher&lt;[String], Never&gt; {
      return $_models.eraseToAnyPublisher()
    }
  }
  
  let viewModel = ViewModel()
  viewModel.models.sink { print($0) }
  </code></pre>
  
  <p>But what if you want to be able to read the value "on demand" as well? For example for this situation:</p>
  
  <pre class="lang-swift prettyprint-override"><code>extension ViewController: UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
      print(viewModel.models[indexPath.row])
    }
  }
  
  </code></pre>
  
  <p>Obviously, the above code doesn't work. </p>
  
  <p>I thought about using a <code>CurrentValueSubject</code>, but its value is writable too, plus I'm having a hard time turning a Publisher into a CurrentValueSubject anyway. </p>
  
  <p>My current solution is to add something like this on the viewmodel:</p>
  
  <pre class="lang-swift prettyprint-override"><code>class ViewModel {
    @Published private var _models = ["hello", "world"]
    @Published var selectedIndex: Int?
  
    var models: AnyPublisher&lt;[String], Never&gt; {
      return $_models.eraseToAnyPublisher()
    }
  
    var selectedModel: AnyPublisher&lt;String, Never&gt; {
      return models.combineLatest($selectedIndex.compactMap { $0 }).map { value, index in
        value[index]
      }.eraseToAnyPublisher()
    }
  }
  
  let viewModel = ViewModel()
  viewModel.models.sink { print($0) }
  
  viewModel.selectedModel.sink { print($0) }
  viewModel.selectedIndex = 1
  </code></pre>
  
  <p>But it's a bit of a chore to add the <code>selectedIndex</code> property, the <code>selectedModel</code> publisher, set the selectedIndex and subscribe to the publisher.. all because I want to be able to read the current value of <code>viewModel.models</code> (and not have it writable).</p>
  
  <p>Any better solutions?</p>