Combine vs RxSwift: Introduction to Combine & differences
Tags: webdev, swift, combine
Published: 2020-03-10 10:15:21

---
title: Combine vs RxSwift: Introduction to Combine & differences
published: true
tags: web development,swift, combine
canonical_url: https://apiumhub.com/tech-blog-barcelona/combine-vs-rxswift-differences/
---

In today’s article I’d like to give an **introduction to Combine** and show its main **differences with RxSwift** , and probably the best way to start is by showing Apple’s definition of Combine:

> A unified, declarative API for processing values overtime

I’m sure it sounds familiar; that’s because, as we’ve said earlier, in this article we’ll talk about some of the similar features and differences between `Combine` and `RxSwift`, starting with Combine and its main features.

## Combine vs RxSwift: Introduction to Combine

We’ll start by highlighting Combine’s three main attributes

- Generic.
- Type safe.
- Composition first. 

Apple tells us in their Combine keynote that the main concepts are simple and easy to understand, but once combined they allow for more complex and interesting stuff to be done.

Within Combine we’ll find:

- Publishers 
- Subscribers 
- Operators

### Publishers

Publishers are the most declarative part of Combine’s API. They define how values and errors are produced.  
They’re **Value type** , in Swift, Structs.  
Publishers allow the subscription of Subscribers, in turn letting us receive values once they’re emitted.

```
protocol Publishers {
    associatedtype Output
    associatedtype Failure: Error

    func subscribe<S: Subscriber>(_ subscriber: S) 
        where S.input == Output, S.Failure == Failure
}

```

### Subscribers

Subscribers are the other side of the publishers coin. They receive values through the stream, and since these can mutate they are **Reference types** , like classes.

```
protocol Subscriber {
    associatedtype Input
    associatedtype Failure: Error

    func receive(subscription: Subscription)
    func receive(_ input: Input) -> Subscribers.Demand
    func receive(completion: Subscribers.Completion<Failure>)

}

```

### This reminds me of something…

Looking at these basic Combine concepts we can deduce that it is very similar to other existing reactive programming frameworks like RxSwift or ReactiveCocoa. For now, let’s focus on how it compares to RxSwift.

If you’re familiar with RxSwift you’ll notice that `Publishers` are basically `Observables` and `Subscribers` are `Observers`; they have different names but work the same way. A **Publisher** exposes values that can change and a `Subscriber` “subscribes” so it can receive all these changes.

## Combine vs RxSwift: Differences

##### Current compatibility

First off, Combine does not offer _backward compatibility_, that is, it’s not available for systems older than iOS 13 / macOS Catalina, since it needs the new _runtime_ process in order to work. There are no future plans to introduce this backward compatibility.

RxSwift works with iOS 8 and above.

##### Error management

Looking at the specification for the `Observable` protocol we’ll spot the first differences.

In Combine, every `Publisher` needs to specify an error type, while in RxSwift, `Observables` don’t use an error type, instead they can `throw` any type of error at any given moment. This makes RxSwift’s `Observables` easier to use, since you don’t have to think about the types of errors that should be launched. On the other hand, this means you’ll have to be careful when managing errors by yourself, since the compiler won’t help you if you missed one, something that wouldn’t happen with Combine since it’s way more strict.

With Combine, if your stream doesn’t throw errors of any kind you can mark it with the type `Never`.

While this explicit specification of error types can be seen as an extra layer of security, it also adds some complications to the code. Meanwhile, you can get something similar with RxSwift using the `Result` type, which adds an additional error type but your stream wouldn’t stop after throwing an error, or using a specific stream for error management.

There’s another difference regarding error management: Combine separates functions as `throwing` or `non-throwing`. For example, there’re operators that have an error-throwing version and the `non-throwing` one.

##### Performance

_Performance_ wise, and while it’s undeniable that RxSwift is a properly optimized framework, Combine has been built by Apple’s engineers with a 100% focus on performance.

As we can see on [Flawless iOS](https://medium.com/flawless-app-stories/will-combine-kill-rxswift-64780a150d89) blog, they did a comparison executing two code blocks doing the same work, one with Combine and the other with RxSwift, and we can observe that Combine’s time _performance_ is the winner.

![Alt Image Text](https://miro.medium.com/max/1904/1*nQg-PRjr3kvlF7JSxMxT8g.png "Performance")

One of the main reasons for this improvement is because RxSwift uses Swift as its main language and thus needs to do a lot of `sinks` on the frameworks’ lower layers, affecting its performance. On the other hand, Combine is a Close Source project, and might not have necessarily been developed using Swift (but can expose a public Swift interface). Apple can use a lot of performance optimizations not available to developers outside of the company.

##### Operators

Combine and RxSwift have a lot of operators doing the same or a very similar job, but with a different _naming_.

Thankfully, the chart created by [Shai Mishali](https://medium.com/flawless-app-stories/will-combine-kill-rxswift-64780a150d89) can help us link all these operators with different names.

##### Open source

An important element that we’ve mentioned before is that Combine is not an open source project, something pretty logic if we take into account that the rest of Apple frameworks aren’t either. It’s feasible that Combine uses system _features_ only available to Apple developers, but even if it was open source, Apple would still have a bigger advantage when tackling potential problems related to their core.

##### DisposeBag

You’re probably already familiar with RxSwift memory management pattern, DisposeBag. Instead of storing each subscription separately and ending them when the controller or class deinitializes, we simply write `.disposed(by: disposeBag)` and the framework will detect the `deinit` and get rid of all those Rx dependencies.

Combine doesn’t have anything similar to `DisposeBag`.

##### UI Framework

Inside a reactive framework we need some way to link the reactive flows to the view, and vice versa. RxSwift’s solution is `RxCocoa`.

Combine doesn’t have a specific framework to do these _binds_, instead we can use the `assign` method to link a `stream` to a _key path_ and a view property.

`publisher.assign(to: \.text, on: label)`

Combine (still) doesn’t have a way to obtain a stream from a UI component in the same way we can with `RxCocoa`.

##### Conclusion

Mi opinion, leaving aside the differences between these frameworks, is that the creation of more reactive programming tools is very positive for Swift. It’s possible that the Combine’s emergence will give a popularity push to RxSwift, and during the next years, as Combine keeps maturing, at some point it might be worth it to jump straight into Apple’s framework. For the moment, and seeing how it has no backward compatibility, we can still enjoy RxSwift.

The post [Combine vs RxSwift: Introduction to Combine & differences](https://apiumhub.com/tech-blog-barcelona/combine-vs-rxswift-differences/) appeared first on [Apiumhub](https://apiumhub.com).