0

I am coming from RxSwift and usually end up binding PublishSubjects together. I see that in Combine PassthroughSubject is the equivalent.

I have tried the following code:

let passthroughSubject1 = PassthroughSubject<Void, Never>()
let passthroughSubject2 = PassthroughSubject<Void, Never>()

private func bindEvents() {
    passthroughSubject1
        .assign(to: \.passthroughSubject1, on: self)
        .store(in: &cancellables)
}

However I get the error Key path value type 'PassthroughSubject<Void, Never>' cannot be converted to contextual type 'Void'.

Is there not a way to bind two subjects together in Combine?

Kex
  • 8,023
  • 9
  • 56
  • 129
  • What does `binding` mean for you? What would you expect from such functionality? – Cristik Jun 07 '22 at 08:45
  • Like an RxSwift binding. eg `passthroughSubject1.bind(to: passthroughSubject2)` so when `passthroughSubject1` is triggered it will pass the event along to `passthroughSubject2`. More elegant than using sink `{ [weak self] _ in self?. passthroughSubject2.(()) }` – Kex Jun 07 '22 at 09:20
  • OK, but I still fail to see what's your exact need. Why do you need this "binding" functionality? Can you update the question and add a concrete usage example? – Cristik Jun 07 '22 at 12:02

1 Answers1

0

It seems you are mixing up different things.

The assign operator is used to set variables. In your example you are trying to set passthroughSubject1 of type PassthroughSubject<Void,Never> to type Void.

So this would work:

var passthroughSubject1 = PassthroughSubject<String,Never>() //changed Void to String
var variable1: String = ""#
var store = Set<AnyCancellable>()

passthroughSubject1.assign(to: \.variable1, on: self)
  .store(in: &store)

I do not know what you mean with:

end up binding PublishSubjects together

but if you want to chain them (emitting with passthroughSubject2 when passthroughSubject1 is emitting a value) you would use a sink.

var passthroughSubject1 = PassthroughSubject<Void,Never>()
var passthroughSubject2 = PassthroughSubject<Void,Never>()

passthroughSubject1.sink(receiveValue: {[weak self] in
    self?.passthroughSubject2.send()
}).store(in: &store)

If you want to react when one of the two publishers emits a value you can use the Publishers.CombineLatest function:

Publishers.CombineLatest(passthroughSubject1, passthroughSubject2)
    .sink(receiveValue: {_,_ in
        // one of the two publishers emitted a value
    }).store(in: &store)     

documentation for assign(to:on:)

burnsi
  • 6,194
  • 13
  • 17
  • 27