Swift Combine — Deep Dive into Publisher, Subscriber and Subscription Protocols
In the previous article, we have learnt about ‘Assign’ subscriber. We will understand default protocols of ‘Publisher’, ‘Subscriber’ and ‘Subscription’ in this article so you will have understanding of internal workings of these.
If you are directly coming to this article, basic knowledge of subscriber, publisher and subscription is expected. If you wish to revise feel free to revisit the learning series.
In our article about combine basics, we have learnt that, to create a subscription, both Publisher and Subscriber play significant role. An image paints a thousand words, so to start off, let’s use one to demonstrate the internal working between publishers and subscribers.
Image itself is a self explanatory. All 5 steps plays crucial role during any subscription. Let’s try to break out all those steps and understand via actual protocols of each from the Combine framework.
Publisher Protocol
Try to write ‘Publisher’ in a xcode playground and see its implementation (press Command + Control keys), which says ‘It is a type that transmits sequence of events over time’
Let’s try to understand ‘Publisher’ protocol.
// 1
public protocol Publisher {
// 2
associatedtype Output
// 3
associatedtype Failure : Error
// 4
func receive<S>(subscriber: S) where S : Subscriber,
Self.Failure == S.Failure,
Self.Output == S.Input
}
extension Publisher {
// 5
public func subscribe<S>(_ subscriber: S) where S : Subscriber,
Self.Failure == S.Failure,
Self.Output == S.Input
}
- Default ‘Publisher’ protocol available from the Combine Framework.
- The kind of the output values published by this publisher.
- The kind of errors this publisher might publish. Use `Never` if this `Publisher` does not publish errors.
- Attaches the specified subscriber to this publisher. This is a required method to implement for any Publisher. Where:
Incoming subscriber must be adopting ‘Subscriber’ protocol.
Publisher’s output type must match with Subscriber’s input type.
‘Failure’ of subscriber and Publisher must be of same type. - Function ‘subscribe’ which takes a subscriber as a parameter with same conditions like step #4 function.
Always call ‘subscribe’ function to attach any subscriber to the Publisher. This method internally calls ‘receive’ method. (Step #1 in above communication diagram)
Subscriber Protocol
Try to write ‘Subscriber’ in a xcode playground and see its implementation (press Command + Control keys), which says ‘A protocol that declares a type that can receive input from a publisher.’
Let’s try to understand ‘Subscriber’ protocol.
// 1
public protocol Subscriber : CustomCombineIdentifierConvertible {
// 2
associatedtype Input
// 3
associatedtype Failure : Error
// 4
func receive(subscription: Subscription)
// 5
func receive(_ input: Self.Input) -> Subscribers.Demand
// 6
func receive(completion: Subscribers.Completion<Self.Failure>)
}
- Default ‘Subscriber’ protocol available from the Combine Framework.
- The kind of values this subscriber receives.
- The kind of errors this publisher might publish. Use `Never` if this `Subscriber` does not receive errors.
- Defines that requested subscription is already successful from the Publisher side. Subscriber may request items. (Step #2 in above communication diagram)
Subscriber receives instance of the subscription as a parameter of this method. - Gets called when there is any event received from the Publisher event. This will get called for every emitted events from the Publisher. Subscriber can adjust its demand about future events in return, if it wants. (Will see more about ‘Demand’ in our next custom subscriber article) (Step #4 in above communication diagram)
- Gets called when Publisher sends a completion event either with success or failure. (Step #5 in above communication diagram)
Subscription Protocol
Try to write ‘Subscription’ in a xcode playground and see its implementation (press Command + Control keys), which says ‘A protocol representing the connection of a subscriber to a publisher.’
Let’s try to understand ‘Subscription’ protocol.
// 1
public protocol Subscription : Cancellable,
CustomCombineIdentifierConvertible {
// 2
func request(_ demand: Subscribers.Demand)
}
- Default ‘Subscription’ protocol available from the Combine Framework.
- Calling this method on any subscription instance tells a publisher that it may send more values to the subscriber.
It takes ‘Subscribers.Demand’ as a parameter, which tells Publisher about either more events to publish to the subscriber or not.
Cancellable
Notice that Subscription protocol confirms to ‘Cancellable’ protocol. When a subscriber completes its task and no longer wishes to receive values from a publisher, canceling the subscription is a recommended practice to release resources and prevent any related activities such as any current / future network calls related to that subscription.
When any subscription is successful, subscriber of that subscription always receives a unique ‘Cancellation Token’ using which particular subscription can be cancelled any time as per need basis. Cancellation Token defines identity of any Subscription.
If you don’t explicitly invoke cancel function on a subscription, it will persist until the publisher finishes transmission of the events or until standard memory management causes a stored subscription to be deinitialized.
Make sure cancelling a subscription must be thread-safe.
Summary
- Publisher will have one important method to allow subscription from the subscriber.
- Subscriber relies on three methods responsible for receiving a created subscription instance, receiving a values and receiving a completion.
- Subscription can request values using ‘Demand’ to the publisher. Those values will be received by the subscriber.
- Any subscription can be cancelled by calling ‘cancel’ method on it.
We have understood default protocols of the Publisher, Subscriber and Subscription. We will explore creating a ‘Custom Subscriber’ in our next article. Stay tuned with the combine learning series.
Feel free to follow me to stay updated with the upcoming articles.
Thank You. Cheers!
#Pre-Requisite
Intermediate level of the swift language / iOS is required for this Combine Article series.
#Credits