Introducing Combine Framework
Lets deep dive on Publisher, Subscriber, Operators and Subjects
Functional Reactive Programming
Apple’s Combine framework introduced during WWDC 2019, it allows you to write functional reactive code by providing a declarative Swift API. In other words, it implements FRP model similar to that of RX by RXSwift and ReactiveSwift. The combine is useful in applications that have data that changes over time. For example, user interface events, network calls and other asynchronous data.
Combine = Publisher + Operators + Subscriber
In this article we are going to focus on the main concepts of Combine
- Publisher — Sends sequence of values over time to one or more subscribers
- Operators — Its a special methods that returns another Publiser
- Subscriber — It receives value from the Publisher
- Subjects — Publisher that insert values from outside into the stream
Publisher and Subscriber
The Combine publisher transmits a single value or multiple values or no value at all. The Foundation framework and SwiftUI provides additional convenience publishers like; dataTaskPublisher, Timer, NotificationCenter, Result and @Published, @ObservedObject property wrappers to supports its declarative mechanisms.

In the networking layer, once we create a publisher, we attached a subscription to it by using the sink API, which has a closure with a completion handler and receiving value. This publisher always returns an object that conforms to Cancellable protocol which acts as a new subscription. The subscriptions are canceled when the object that is holding on to AnyCancellable is deallocated. You can also manually cancel it by calling cancel().

NotificationCenter is also one of the build-in publisher, where we can subscribe to the notification by using publisher.

You can use combine for Timer to get periodic time updates, it can also be trigger automatically or manually.

@Published is a property wrapper, which can attach a publisher to a single variable (i.e isSubmitEnabled). In the above example, the submit button should be enabled only if the terms switch is checked. So the $ is added as a prefix to the variable similar to binding the object and .assign is subscribe to value change. Any change to isSubmitEnabled value will bounds to submit button to assign the property .isEnabled on the main queue as we’re working with UI.
Subjects
The Subjects can send a value between Publisher and Subscriber. There are two types of build-in subjects,
- PassthroughSubject — A subject that broadcasts elements to downstream subscribers.
- CurrentValueSubject — It holds the current value when a subscriber is triggered. Creates a current value subject with the given initial value.

Operators
Combine ships with multiple operators which transform the publishers in different ways. It used to build reactive chains or pipelines that our data can flow through.

let numbers = (1...100).publisher
numbers.dropFirst(50)
.prefix(20)
.filter { $0 % 2 == 0 }
.sink {print($0)}
The above code is used to filtering the even numbers from a range of 50–70. So the first step is to use dropFirst operator to skip the first 50 values emitted by the upstream publisher. Then take the next 20 values after those first 50 values using prefix and filter only the even numbers.

There is a chain of operators to return AnyPublisher<Weather, Error>. .print() is used to log the lifecycle of Combine flow. .map is to get the response data and .decode it to transform the data into WeatherResponse object which conforms to decodable protocol. Now I’m going to optimise the decode operator by extending the JSONDecoder and Publisher.


The sink operator is used to handle the result with two closures — one for handling each output value, and one for handling completion events. It is a bit inconvenient so it’s always better to have a Result value to access success and failure. Now its time to create a custom operator to change the result type.



Conclusion
Combine is an exciting and powerful framework with a ton of different APIs and capabilities. By adopting Combine, you’ll make your code easier to read and maintain, by centralizing your event-processing code and eliminating troublesome techniques like nested closures and convention-based callbacks. You can find a sample app with combine framework on Github.