Search code examples
swiftcombine

How to chain together two Combine publishers in Swift and keep the cancellable object


Does anyone know how to chain together two publishers with Swift + Combine and keep the cancellable so that I can cancel the pipeline later? I have a method that accepts input from a publisher and outputs to a publisher:

static func connect(inputPublisher: Published<String>.Publisher, outputPublisher: inout Published<String>.Publisher) -> AnyCancellable {
    inputPublisher.assign(to: &outputPublisher)

    // Unfortunately assign consumes cancellable
}

Note that this method cannot access the wrapped properties directly. The publishers must be passed as arguments.


Solution

  • If I understand correctly, you want to link two publishers but with the option to break that link at some point in the future.

    I would try using sink on the inputPublisher, since that function gives me a cancellable, and then a PassthroughSubject, since I wasn't able to figure out how to pass the value from sink directly to outputPublisher.

    It would look something like this:

    static func connect(inputPublisher: Published<String>.Publisher, outputPublisher: inout Published<String>.Publisher) -> AnyCancellable {
      let passthrough = PassthroughSubject<String, Never>()
      passthrough.assign(to: &outputPublisher)
      let cancellable = inputPublisher.sink { string in
        passthrough.send(string)
      }
      return cancellable
    }
    

    Disclaimer: I wrote this on a Playground and it compiles, but I didn't actually run it.