In the previous section, we looked at promises and futures, trying to get a thorough understanding of the way they work and presenting two popular promises frameworks that help you use promises in your programs. Here, we will consider a completely different approach to asynchronous computation, Reactive Programming (RP). The basic idea behind RP is that of asynchronous data streams, such as the stream of events that are generated by mouse clicks, or a piece of data coming through a network connection. Anything can be a stream; there are really no constraints. The only property that makes it sensible to model any entity as a stream is its ability to change at unpredictable times. The other half of the picture is the idea of observers, which you can think of as agents that subscribe to receive notifications of new events in a stream. In between, you have ways of transforming those streams, combining them, creating new streams, filtering them, and so on.
A related but ultimately deeply different idea to RP is Functional Reactive Programming (FRP). In somewhat abstract terms, you could think of FRP as a declarative approach to describing the relationship between timed entities, that is, entities whose value changes continuously. For example, you could use FRP to describe the relationship a = b + c. You may see some similarity between RP and FRP. Indeed, in this example, you could think of having a subscribe to both b and c for any change to their values, so a can recalculate its own value accordingly. In fact, RP and FRP are not the same, since RP lacks a declarative notation and works in discrete time, generated by the arrival of discrete events.
In the remaining part of this section, we will give a light introduction to one popular framework for RP in Swift, RxSwift, and its Cocoa counterpart, RxCocoa, to make Cocoa ready for use with RP. RxSwift is not the only RP framework for Swift. Another popular one is ReactiveCocoa, but we think that, once you have understood the basic concepts behind one, it won't be hard to switch to the other.
You could look at RP as a generalization of
Key-Value Observing (
KVO), a mechanism that is present in the macOS and iOS SDKs since their inception. KVO enables objects to receive notifications about changes to other objects' properties to which they have subscribed as observers. An observer object can register by providing a keypath, hence the name, into the observed object. Unfortunately, KVO is partially broken in Swift, at least up to Swift 4.2, and your app may crash when the KVO
keyPathsForValuesAffectingValue method is run on a background thread while the main thread is attempting to register an observer, for example, to update a UI element. See this radar issue (
https://bugs.swift.org/plugins/servlet/mobile#issue/SR-6795) for more details.