Combine - Creating your own Publishers with PassthroughSubject and CurrentValueSubject

Before reading this article, I recommend you guys first read my other Combine articles mentioned below for a better understanding.

To read, Combine Framework Beginner Tutorial in Swift, Click Here.

To read, Combine - Processing Values with Operators in Swift, Click Here.

To read, Combine - Creating your own Publisher with @Published, Click Here.

Let’s Start

There’s not much difference between the PassthroughSubject or CurrentValueSubject, just a mere change that CurrentValueSubject stores your value in a property name value, and this allows us to access the value of the subject at any point. Let me show you how both of them works with example.

E.g. PassthroughSubject

var passthroughSubject = PassthroughSubject() // Creating the PassthroughSubject

let cancellable = passthroughSubject
    .sink { value in
        print("New value: \(value)")
}

passthroughSubject.send(5)
passthroughSubject.send(10)
//passthroughSubject.value  //Passthroughsubject does not have this property

/*
 Output:
 New value: 5
 New value: 10
 */

That’s how we use PassthroughSubject, and as I have mentioned in the comment, PassthroughSubject does not have the value property which you can see in our next example of CurrentValueSubject.

E.g. CurrentValueSubject

var currentValueSubject = CurrentValueSubject(1) // Creating CurrentValueSubject

let cancellable = currentValueSubject
    .sink { value in
        print("New value: \(value)")
}

currentValueSubject.send(5)
currentValueSubject.send(10)

currentValueSubject.send(completion: .finished) // After calling completion, publisher stops emitting values.

currentValueSubject.send(15) // Value for this statement is not printed as expected.

print("Current Value: \(currentValueSubject.value)") // Accessing "value", and the latest value sent is printed.

/*
 Output:
 New value: 1
 New value: 5
 New value: 10
 Current Value: 10
 */

If you look in the example above, after calling the send(_:) function two times with value 5 and 10, we have called send(completion:) with .finished as argument. Which here means is that the sink(receiveValue:) will stop printing our new values.

As expected when we call send(_:) with a value of 15, nothing is printed on the screen.

On the next line, we have accessed the value with the help of the value property in our CurrentValueSubject object.

CurrentValueSubject is used when you need the subject to act as a variable that stores value and can be retrieved whenever required.

Bonus

Publisher is everywhere. All those strings, arrays and dictionaries you see can act as a publisher. Simply start with .publisher(). Confused?

let arrayPublisher = ["H","E","L","L","O"].publisher
let stringPublisher = "World".publisher

let arrayCancellable = arrayPublisher.sink { value in
    // Process value
}

let stringCancellable = stringPublisher.sink { value in
    // Process value
}

Isn’t it great? Reply to me on Twitter.

I hope you guys enjoyed reading my article. There’s a lot more to learn together, so subscribe to stay updated about my upcoming articles.

If you have any suggestions or questions, Feel free to connect me on Twitter or Reddit. 😉

How to use UIColorPickerViewController in Swift?

Combine - Creating your own Publisher with @Published