RxSwift helps when you need to combine complex asynchronous chains. RxSwift also has types such as Subject, a kind of bridge between the imperative and declarative worlds. The subject can act as an Observable, and at the same time, it can be an Observer, i.e. accept objects and issue events.
There will still be many legacy projects written in UIKit for some years to come, and RxSwift (along with RxCocoa) is an excellent choice for reactive UIKit apps. Experience with RxSwift is going to be a valuable skill on your resume for some time yet.
Rx-Swift is a reactive programming library in iOS app development. It is a multi-platform standard, its difficult-to-handle asynchronous code in Swift, that becomes much easier in Rx-Swift. RxSwift makes easy to develop dynamic applications that respond to changes in data and respond to user events.
RxSwift library allows us to use Swift disparately. With this library, asynchronous programming becomes easier to do and more legible. It allows you to build more solid architectures and applications with higher quality. RxCocoa library allows us to use Cocoa APIs used in iOS and OS X with reactive technics.
This is a very good question. Comparing the two worlds is very hard. Rx is a port of what Reactive Extensions are in other languages like C#, Java or JS.
Reactive Cocoa was inspired by Functional Reactive Programming, but in the last months, has been also pointed as inspired by Reactive Extensions as well. The outcome is a framework that shares some things with Rx, but has names with origins in FRP.
The first thing to say is that neither RAC nor RxSwift are Functional Reactive Programming implementations, according to Conal's definition of the concept. From this point everything can be reduced to how each framework handles side effects and a few other components.
Let's talk about the community and meta-tech stuff:
Now it's time for the tech stuff.
RAC 3.0 has 2 main entities, Signal
and SignalProducer
, the first one publishes events regardless a subscriber is attached or not, the second one requires a start
to actually having signals/events produced. This design has been created to separate the tedious concept of hot and cold observables, that has been source of confusion for a lot of developers. This is why the differences can be reduced to how they manage side effects.
In RxSwift, Signal
and SignalProducer
translates to Observable
, it could sound confusing, but these 2 entities are actually the same thing in the Rx world. A design with Observable
s in RxSwift has to be created considering if they are hot or cold, it could sound as unnecessary complexity, but once you understood how they work (and again hot/cold/warm is just about the side effects while subscribing/observing) they can be tamed.
In both worlds, the concept of subscription is basically the same, there's one little difference that RAC introduced and is the interruption
event when a Signal
is disposed before the completion event has been sent.
To recap both have the following kind of events:
Next
, to compute the new received valueError
, to compute an error and complete the stream, unsubscribing all the observersComplete
, to mark the stream as completed unsubscribing all observersRAC in addition has interrupted
that is sent when a Signal
is disposed before completing either correctly or with an error.
In RAC, Signal
/SignalProducer
are read-only entities, they can't be managed from outside, same thing is for Observable
in RxSwift. To turn a Signal
/SignalProducer
into a write-able entity, you have to use the pipe()
function to return a manually controlled item. On the Rx space, this is a different type called Subject
.
If the read/write concept sounds unfamiliar, a nice analogy with Future
/Promise
can be made. A Future
is a read-only placeholder, like Signal
/SignalProducer
and Observable
, on the other hand, a Promise
can be fulfilled manually, like for pipe()
and Subject
.
This entity is pretty much similar in both worlds, same concepts, but RAC is serial-only, instead RxSwift features also concurrent schedulers.
Composition is the key feature of Reactive Programming. Composing streams is the essence of both frameworks, in RxSwift they are also called sequences.
All the observable entities in RxSwift are of type ObservableType
, so we compose instances of Subject
and Observable
with the same operators, without any extra concern.
On RAC space, Signal
and SignalProducer
are 2 different entities and we have to lift
on SignalProducer
to be able to compose what is produced with instances of Signal
. The two entities have their own operators, so when you need to mix things, you have to make sure a certain operator is available, on the other side you forget about the hot/cold observables.
About this part, Colin Eberhardt summed it nicely:
Looking at the current API the signal operations are mainly focussed on the ‘next’ event, allowing you to transform values, skip, delay, combine and observe on different threads. Whereas the signal producer API is mostly concerned with the signal lifecycle events (completed, error), with operations including then, flatMap, takeUntil and catch.
RAC has also the concept of Action
and Property
, the former is a type to compute side effects, mainly relating to user interaction, the latter is interesting when observing a value to perform a task when the value has changed. In RxSwift the Action
translates again into an Observable
, this is nicely shown in RxCocoa
, an integration of Rx primitives for both iOS and Mac. The RAC's Property
can be translated into Variable
(or BehaviourSubject
) in RxSwift.
It's important to understand that Property
/Variable
is the way we have to bridge the imperative world to the declarative nature of Reactive Programming, so sometimes is a fundamental component when dealing with third party libraries or core functionalities of the iOS/Mac space.
RAC and RxSwift are 2 complete different beasts, the former has a long history in the Cocoa space and a lot of contributors, the latter is fairly young, but relies on concepts that have been proven to be effective in other languages like Java, JS or .NET. The decision on which is better is on preference. RAC states that the separation of hot/cold observable was necessary and that is the core feature of the framework, RxSwift says that the unification of them is better than the separation, again it's just about how side effects are managed/performed.
RAC 3.0 seems to have introduced some unexpected complexity on top of the major goal of separating hot/cold observables, like the concept of interruption, splitting operators between 2 entities and introducing some imperative behaviour like start
to begin producing signals. For some people these things can be a nice thing to have or even a killer feature, for some others they can be just unnecessary or even dangerous. Another thing to remember is that RAC is trying to keep up with Cocoa conventions as much as possible, so if you are an experienced Cocoa Dev, you should feel more comfortable to work with it rather than RxSwift.
RxSwift on the other hand lives with all the downsides like hot/cold observables, but also the good things, of Reactive Extensions. Moving from RxJS, RxJava or Rx.Net to RxSwift is a simple thing, all the concepts are the same, so this makes finding material pretty interesting, maybe the same problem you are facing now, has been solved by someone in RxJava and the solution can be reapplied taking in consideration the platform.
Which one has to be picked is definitely a matter of preference, from an objective perspective is impossible to tell which one is better. The only way is to fire Xcode and try both of them and pick the one that feels more comfortable to work with. They are 2 implementations of similar concepts, trying to achieve the same goal: simplifying software development.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With