title: ReactiveSwift: How to subscribe to SignalProducer?
body: <p>I'm trying to learn ReactiveSwift and ReactiveCocoa. I can use <code>Signal</code> and <code>Property</code> pretty well, but I'm having trouble with <code>SignalProducer</code>.</p>
  
  <p>As I understand it, <code>SignalProducer</code> is ideal for things like network requests. I set up my API layer to create and return a signal provider, which the caller can start.</p>
  
  <pre><code>class ApiLayer {
      func prepareRequest(withInfo info: RequestInfo) -&gt; SignalProducer&lt;ModelType, ErrorType&gt; {
          return SignalProducer&lt;ModelType, ErrorType&gt; { (observer, lifetime) in
  
              // Send API Request ...
  
              // In Completion Handler:
              let result = parseJson(json)
              observer.send(value: result)
              observer.sendCompleted()
          }
      }
  }
  </code></pre>
  
  <p><strong>But how am I supposed to listen for the results?</strong></p>
  
  <p>I've tried something like this, but I get an error, so I must be doing / thinking about this wrong.</p>
  
  <pre><code>apiLayer.prepareRequest(withInfo: info)
      .startWithValues { (resultModel) in
          // Do Stuff with result ...
  }
  </code></pre>
  
  <p>Here's the error I get:</p>
  
  <blockquote>
    <h2>Ambiguous reference to member 'startWithValues'</h2>
    
    <ol>
    <li>Found this candidate (ReactiveSwift.SignalProducer&lt; Value, NoError >)</li>
    <li>Found this candidate (ReactiveSwift.SignalProducer&lt; Never, NoError >)</li>
    </ol>
  </blockquote>
  
  <p><strong>EDIT</strong></p>
  
  <p>I tried being more explicit to help the compiler identify the proper method, like so. But the error still remains.</p>
  
  <pre><code>apiLayer.prepareRequest(withInfo: info)
      .startWithValues { (resultModel: ModelType) in // Tried adding type. Error remained.
          // Do Stuff with result ...
  }
  </code></pre>
  
  <p><strong>EDIT 2</strong></p>
  
  <p>After getting help over at the GitHub support page and thinking about the provided answer here, here's what I ended up with.</p>
  
  <p>One key difference from my earlier attempts is that the caller doesn't manually start the returned <code>SignalProducer</code>. Rather, by creating it inside/in response to another signal, it's implicitly started inside the chain.</p>
  
  <p>I had previously (incorrectly) assumed that it was necessary to extract and explicitly subscribe to the <code>Signal</code> that a <code>SignalProducer</code> "produced".</p>
  
  <p>Instead, I now think about <code>SignalProducer</code>s simply as deferred work that is kickstarted in response to stimuli. I can manually subscribe to the <code>SignalProvider</code> or I can let another <code>Signal</code> provide that stimulus instead. (The latter used in my updated sample below. It seems fairly clean and much more FRP-esque than manually starting it, which I had carried over from my imperative mindset.)</p>
  
  <pre><code>enum ErrorType: Error {
      case network
      case parse
  }
  class ApiLayer {
      func prepareRequest(withInfo info: RequestInfo) -&gt; SignalProducer&lt;ModelType, ErrorType&gt; {
          let producer = SignalProducer&lt;ResultType, NoError&gt; { (observer, lifetime) in
  
              sendRequest(withInfo: info) { result in
                  observer.send(value: result)
                  observer.sendCompleted()
              }
  
          }
  
          return producer
              .attemptMap { result throws -&gt; ResultType in
                  let networkError: Bool = checkResult(result)
                  if (networkError) {
                      throw ErrorType.network
                  }
              }
              .retry(upTo: 2)
              .attemptMap { result throws -&gt; ModelType in
                  // Convert result
                  guard let model: ModelType = convertResult(result) else {
                      throw ErrorType.parse
                  }
                  return model
              }
              // Swift infers AnyError as some kind of error wrapper.
              // I don't fully understand this part yet, but to match the method's type signature, I needed to map it.
              .mapError { $0.error as! ErrorType}
      }
  }
  
  // In other class/method
  // let apiLayer = ApiLayer(with: ...)
  // let infoSignal: Signal&lt;RequestInfo, NoError&gt; = ...
  infoSignal
      .flatMap(.latest) { (info) in
          apiLayer.prepareRequest(withInfo: info)
      }
      .flatMapError { error -&gt; SignalProducer&lt;ModelType, NoError&gt; in
          // Handle error
          // As suggested by the ReactiveSwift documentation,
          // return empty SignalProducer to map/remove the error type
          return SignalProducer&lt;ModelType, NoError&gt;.empty
      }
      .observeValues { model in
          // Do stuff with result ...
      }
  </code></pre>