Swift Combine Framework in Nutshell
Combine was introduced as a new framework by Apple at WWDC 2019. The framework provides a declarative Swift API for processing values over time. It is widely used by developers to unify and simplify code dealing with things like delegates, notification, timers, completions blocks and callbacks. It can be seen as a 1st party alternative to popular framework like RxSwift and ReactiveSwift.
It’s a reactive framework which allow us to do asynchronous code. Combine has some core concepts that we need to understand
· Publisher
· Subscriber
· Subjects
· Operator
Publisher
· Defines how values and errors are produced
· Value type
· Allows registration of a subscriber
The publisher is a protocol that has two associated type -
1- Output:- value reproduced by publisher
2- Failure:- error produced by publisher
The publisher has one key function which is called subscriber. This function requires subscriber input as a parameter to match with the publisher’s output.
Subscriber
· Receives values and a completion
· Reference type
Subscriber is a protocol that has two associated types, one for Input and the second for failure.
Input — Type of values subscriber receives
Failure — Types of error publisher emits
A publisher is a push-based interface, which delivers its values to one or more Subscribers based on their demand.
Publisher<Output, Failure>
Subscriber<Input, Failure:>
Output type & error type must match between publisher & Subscriber.
The only thing missing is a piece to connect the subscriber to the publisher so they can communicate with each other
A subscription represents the connection between a publisher and a subscriber and is where most of the “heavy work” happens
The Subscription pushes events to subscribers via 2 different receive methods.
Once you are done with the specific subscription, you can cancel it using its cancel() method. Canceling a subscription will release any memory and resources allocated by the attached subscriber.
The control is transitioned to the Subscriber, which demands a specific amount of values it’s willing to handle.
Subject
A subject is a special kind of publisher you can manually send values to, which is quite useful for bridging imperative code.
A subject can also broadcast values to multiple subscribers by calling it’s send( : ) method. If multiple subscribers are connected to a subject.
There are two types of built-in subjects with Combine:
· PassthroughSubject
· CurrentValueSubject
PassthroughSubject
The PassthroughSubject provides a convenient way to adapt existing imperative code to the combine model.
A PassthroughSubject doesn’t have an initial value or a buffer of the most recently- published element.
CurrentValueSubject
A subject that wraps a single value and publishes a new element whenever the value changes.
Unlike PassthroughSubject, CurrentValueSubject maintains a buffer of the most recently published element.
Calling send( : ) on a CurrentValueSubject also updates the current value, making it equivalent to updating the value directly.
In Nutshall
First, the Subscriber and Publisher are connected. Once they’re connected, the Publisher provides a Subscription to the Subscriber.
At this point, the Subscriber and Subscription interact amongst themselves on how many values the Subscription may produce.
Consuming Publisher
So now I have a bunch of Publishers. To consume Publishers there are two built-in subscriber in Combine sink & assign.
Sink
Sink is a closure-based subscriber.
It takes two closures the first closure executes where the received subscriber completion gets the update whether the publisher finish normally or failed with an error.
The second closure executes when it receives an element from the publisher.
Assign
Assign pushes every emission to the provided key path. It immediately assigns every element it receives to a property of a given object using the key pair.
If assign is being used to update a user interface element then you need to make sure that, the subscriber is received on the main thread.
Getting values is useful, but don’t you wish you could control and modify the values emitted by publishers !?
You can do that using Operators :)
Operators
· Adopts Publisher
· Describes a behavior for changing values
· Subscribes to a Publisher (“upstream”)
· Sends the result to a Subscriber (“Downstrean”)
· Value type
Operators let you manipulate upstream publishers and control the emissions in extremely expressive and flexible ways.
If combine would be a language, operators are the words. The better your vocabulary will be, the more things you can do with your data. There are many operators like Scan, Reduce, combineLatest, zip and Merge etc
Let’s take a simple example of temperature where we wanted to modify the publisher to send only temperatures above 25.
In the above example, I have also created my own custom error enum TemperatureError. We could use that to send a completion error.
Hope you like this article. Please let me know your suggestions,queries, concerns and opinions.