ReactiveCocoa vs RxSwift

A detailed comparison of the two most popular Functional Reactive Programming frameworks for Swift: ReactiveCocoa vs RxSwift! By Colin Eberhardt.

Leave a rating/review
Save for later
Share

Functional Reactive Programming is an increasingly popular programming methodology for Swift developers. It can make complex asynchronous code easier to write and understand.

In this article, you’ll compare the two most popular libraries for Functional Reactive Programming: RxSwift vs. ReactiveCocoa.

You’ll start with a brief review of what Functional Reactive Programming is, and then you’ll see a detailed comparison of the two frameworks. By the end, you’ll be able to decide which framework is right for you!

Let’s get reactive!

What Is Functional Reactive Programming?

Note: If you’re already familiar with the concept of Functional Reactive Programming, skip ahead to the next section, titled “ReactiveCocoa vs RxSwift”.

Even before Swift was announced, Functional Reactive Programming (FRP) has seen
a tremendous rise in popularity in recent years versus Objected Oriented Programming. From Haskell to Go to Javascript, you will find FRP-inspired implementation. Why is this? What’s so special about FRP? Perhaps most importantly, how can you make use of this paradigm in Swift?

Functional Reactive Programming is a programming paradigm that was created by Conal Elliott. His definition has very specific semantics and you are welcome to explore them here. For a more loose/simple definition, Functional Reactive Programming is a combination of two other concepts:

  1. Reactive Programming, which focuses on asynchronous data streams, which you can listen to and react accordingly. To learn more, check out this great introduction.
  2. Functional Programming, which emphasizes calculations via mathematical-style functions, immutability and expressiveness, and minimizes the use of variables and state. To learn more, check out our Swift functional programming tutorial.

Note: André Staltz explores the difference between the original FRP formulation and the practical approach in his article “Why I cannot say FRP but I just did”.

A Simple Example

The easiest way to understand this is through an example. Consider an app that wants to track the user’s location and alert her when she is near a coffee shop.

If you were to program this in an FRP way:

  1. You would construct an object that emits a stream of location events that you can react to.
  2. You would then filter the emitted location events to see which ones are near a coffee shop, and send alerts for those that match.

Here’s what this code might look like in ReactiveCocoa:

locationProducer // 1
  .filter(ifLocationNearCoffeeShops) // 2
  .startWithNext {[weak self] location in // 3
    self?.alertUser(location)
}

Let’s review this section by section:

  1. locationProducer emits an event each time the location changes. Note that in ReactiveCocoa this is called a “signal”, and in RxSwift it’s called a “sequence”.
  2. You then use functional programming techniques to respond to the location updates. The filter method performs exactly the same function as it would on an array, passing each value to the function ifLocationNearCoffeeShops. If the function returns true, the event is allowed to proceed to the next step.
  3. Finally, startWithNext forms a subscription to this (filtered) signal, with the code in the closure expression executed each time an event arrives.

The code above looks very similar to the code you might use for transforming an array of values. But here’s the clever bit … this code is executed asynchronously; the filter function and the closure expression are invoked ‘on demand’ as location events occur.

The syntax might feel a bit strange, but hopefully the underlying intent of this code should be clear. That’s the beauty of functional programming, and why it’s such a natural fit with the whole concept of values over time: it’s declarative. It’s shows you what’s happening, instead of the detail of how it’s being done.

Note: If you want to learn more about the ReactiveCocoa syntax, have a look at a couple of examples I created on GitHub.

Transforming Events

In the location example, you only started to observe the stream, without really doing much with the events aside from filtering the locations for those near coffee shops.

Another fundamental piece in the FRP paradigm is the ability to combine and transform these events into something meaningful. For that, you make use of (but are not limited to) higher order functions.

As expected, you will find the usual suspects you learned about in our Swift functional programming tutorial: map, filter, reduce, combine, and zip.

Let’s modify the location example to skip repeated locations and transform the incoming location (which is a CLLocation) into a user-friendly message.

locationProducer
  .skipRepeats() // 1
  .filter(ifLocationNearCoffeeShops) 
  .map(toHumanReadableLocation) // 2
  .startWithNext {[weak self] readableLocation in
    self?.alertUser(readableLocation)
}

Let’s look at the two new lines added here:

  1. The first step applies the skipRepeats operations to the events emitted by the locationProducer signal. This is an operation that doesn’t have an array analogue; it is ReactiveCocoa specific. The function it performs is pretty obvious: repeated events (based on equality) are filtered out.
  2. After the filter function is performed, map is used to transform the event data from one type to another, perhaps from a CLLocation to a String.

By now, you should be starting to see some of the FRP’s benefits:

  • It’s simple, yet powerful.
  • Its declarative approach makes code more understandable.
  • Complex flows become easier to manage and represent.

please tell me more

ReactiveCocoa vs RxSwift

Now that you have a better understanding of what FRP is and how it can help make your complex asynchronous flows easier to manage, let’s look at the two most popular FRP frameworks – ReactiveCocoa and RxSwift – and why you might choose one over the other.

Before diving into the details, let’s take a brief look at the history of each framework.

ReactiveCocoa

The ReactiveCocoa framework started life at GitHub. While working on the GitHub Mac client, the developers found themselves struggling with managing their application data-flows. They found inspiration in Microsoft’s ReactiveExtensions, an FRP framework for C#, and created their own Objective-C implementation.

Swift was announced while the team was working on their v3.0 release in objective-c. They realised that Swift’s functional nature was highly complementary to ReactiveCocoa, so they started work immediately on a Swift implementation, which became v3.0. The version 3.0 syntax is deeply functional, making use of currying and pipe-forward.

Swift 2.0 introduced protocol-oriented programming, which resulted in another significant ReactiveCocoa API change, with the version 4.0 release dropping the pipe-forward operator in favour of protocol extensions.

ReactiveCocoa is a tremendously popular library with more than 13,000 stars on GitHub at the time of writing.

Colin Eberhardt

Contributors

Colin Eberhardt

Author

Over 300 content creators. Join our team.