Functional Reactive Programming using Combine framework

Mahesh Nagpure
4 min readDec 17, 2022

--

Functional Reactive Programming (FRP) languages allow you to process values over time and allow you to deal with asynchronous code. In iOS, the Combine framework allows you to write functional reactive code by providing a declarative Swift API. Combine framework is an alternative to popular frameworks like RxSwift and ReactiveSwift.

Combine has some core concepts that need to be understood.

  • Publisher and Subscriber
  • Subjects
  • Operators

Publisher and Subscriber

Publisher exposes values that can change on which a subscriber subscribes to receive all those updates. Publisher is a protocol which has two associated type first one is Output which is the kind of value reproduced by publisher and second one is Failure which is the kind of error produced by publisher. Publishers have one key function which is called subscribe. This function needs subscriber input as a parameter to match with the publisher’s output.

Subscriber is responsible for requesting data and accepting the data (and possible failures) provided by a publisher. A subscriber is described with two associated types, one for Input and one for Failure. The subscriber initiates the request for data, and controls the amount of data it receives. A subscriber receives a stream of value, completion or failure events from a publisher. There are two built-in subscribers in Combine i.e. sink and assign. Both Assign and Sink conform to the cancellable protocol.

Publisher and Subscriber

Rules of a subscription

  • A subscriber can only have one subscription
  • Zero or more values can be published
  • At most one completion will be called

Subject

Subject is also a type of publisher on which we can subscribe but also dynamically send events to them. Subject exposes a method for outside callers to publish elements.

There are two types of built-in subjects with Combine: PassthroughSubject, CurrentValueSubject.

PassthroughSubject

If you subscribe to it you will get all the events that will happen after you subscribed. When it is created, only the types are defined. When a subscriber is connected and requests data, it will not receive any values until a .send() call is invoked. PassthroughSubject does not maintain any state, it only passes through provided values.

CurrentValueSubject

CurrentValueSubject remembers the current value so that when a subscriber is attached, it immediately receives the current value. When a subscriber is connected and requests data, the initial value is sent. Further calls to .send() afterwards will then pass through values to any subscribers. When it is created currentValueSubject, you do so with an initial value of the relevant output type for the Subject.

Operators

Operators are a convenient name for a number of pre-built functions that are included under Publisher. This describes when and where a particular event is delivered. This is supported by runloop and dispatch queue. The operators can be divided in 5 macro categories, based on how they manipulate the data.

  • Transforming Operators: Collect, Map, FlatMap, FlatMap, ReplaceEmpty, Scan.
  • Filtering Operators: Filter, CompactMap, IgnoreOutput, First, Last, DropFirst, Drop, Prefix.
  • Combining Operators: Prepend, Append, SwitchToLatest, Merge, CombineLatest, Zip.
  • Time Manipulating Operators: Delay, Collect by time, Debounce, Throttle, MeasureInterval.
  • Sequence Operators: Min, Max, First, Last, Output, Count, Contains, AllSatisfy, Reduce.

Example: Data task with combine framework

The Foundation framework contains a lot of extensions to work with Combine. So the most common example is usually the following one.

  • First we make a cancellable storage for your Publisher
  • Then we create a brand new data task publisher object
  • Map the response, we only care about the data part (ignore errors)
  • Decode the content of the data using a JSONDecoder
  • Erase the underlying complexity to a simple AnyPublisher
  • Use sink to display some info about the final value
Data task with combine framework

Benefits of using the Combine framework

@Published usage to bind values to changes

This keyword is a property wrapper and adds a Publisher to any property. A simple example can be a boolean which we assign to the enabled state of a UIButton.

@Published usage to bind values to changes

Combine with MVVM

The Combine framework is perfectly suitable to work in combination with MVVM. Here is an example.

Combine with MVVM

Timer

You can use Combine to get periodic time updates through a publisher

Timer

NotificationCenter

You can also subscribe to notifications by using publishers.

NotificationCenter

Conclusion

In this article, we discussed the Combine framework in swift and Functional Reactive Programming. Also, we look at some benefits of using Combine in reactive programming with some code.

Combine examples, visit our repository on GitHub:
https://github.com/Mahesh471/Combine.git

--

--