Reactive Programming With Swift - Sample Chapter
Reactive Programming With Swift - Sample Chapter
ee
$ 44.99 US
28.99 UK
P U B L I S H I N G
pl
C o m m u n i t y
Cecil Costa
Reactive Programming
with Swift
E x p e r i e n c e
D i s t i l l e d
Reactive Programming
with Swift
Leverage the power of the Functional Reactive Programming
paradigm with Swift to develop robust iOS applications
Sa
m
Cecil Costa
Preface
Apps nowadays are not just sequences of code that are executed synchronously; they are
more like a collection of code that is executed asynchronously, making it difficult to follow
one order. Reactive Programming (or even better, Functional Reactive Programming) is
trending due to it being prepared for this new way of app development. This book will
show to you how to use ReactiveCocoa, the most extended Reactive Programming
framework for iOS and OS X.
Reactive Programming and Functional Programming are, where they come from, and why
you should used them.
Chapter 2, Installing ReactiveCocoa and Using It with Playground, shows you three different
ways of installing ReactiveCocoa: using the git submodule, CocoaPods, and Carthage.
Finally, it also explains how to use it on Playground for performing fast tests.
Chapter 3, Performing UI Events with ReactiveCocoa, gives you the first approach of using
Reactive Programming. You will see how you can validate a form with ReactiveCocoa.
Chapter 4, Network and Change Propagation, starts with the concepts of using asynchronous
calls and introduces you to creating your own signals and controlling them.
Chapter 5, Enhance Your Application Using RAC Extensions, shows you how to create a
small app that uses Reactive Cocoa extensions. A good feature of this chapter is that it uses
different versions of ReactiveCocoa and shows you how to deal with them.
Chapter 6, Using the ReactiveCocoa 4 Style, shows you how to use ReactiveCocoa in a safer
way. Also, you will learn how Signals and SignalProducers replaced RACSignal.
Chapter 7, Testing Your Application, teaches you how to create unit tests, debug an app,
Chapter 8, Migrating a Real Application to ReactiveCocoa, shows you how to convert an app
that was developed without Reactive Programming into an app that uses it.
Introduction to Reactive
Programming
Every day, you'll find something new to explore in terms of computer programming
languages. These can be in the form of a new programming language, framework,
methodology, or even a new paradigm. You can work with all of these to solve a problem
or improve a development process. Reactive programming is a new paradigm that is no
exception to this. The philosophy behind this new paradigm is that an application needs to
focus on what to do and not how to do it. This chapter introduces what this paradigm is
about, where it came from, and what ReactiveCocoa is.
In this chapter we will cover:
What is reactive programming?
The history of reactive programming
Paradigms imperative versus declarative
What is functional programming?
Choosing reactive programming
Swift interactive, safe, and fast
ReactiveCocoa extensions
Migrating to ReactiveCocoa
The future of reactive programming
something changes (the value of a text field, variable value, and so on), other objects that
depend on this value must be notified and react according to the new value.
To visualize it, let's take a look at an example. Imagine that you have a home automation
application. Your application must react according to the device's state; for example, if the
front door is open, your application must know that someone is coming in. Therefore, it can
then switch on the light. When the light is switched on (it doesn't matter whether it is done
because someone has opened the door or manually switched it on), the security camera
must search for the person in the room and try to recognize them. If the person has not been
recognized, the alarm should ring, but if the person is recognized, the alarm must react by
shutting down. The following diagram explains this idea to you in a more visual way:
Keep in mind that everything works like a chain. When the lights are on, your application
must also react by changing its switch state and icon, the camera preview button must be
enabled, and so on.
Once you have understood the previous example, you will have a basic idea of what
reactive programming is; however, you may think that this application can also be used
without including reactive programming. You can, of course, do this, but the problem lies
in how you do it.
The traditional style of programming is based on how to do things. This means that you
have to create many observers, making development more difficult and fragile as you have
to be aware of every part of the chain, especially when adding new requirements.
[8]
Chapter 1
Reactive programming is based on a different way of development. Basically, you just have
to create rules and when anything happens, the rules are to be followed. It is different from
the traditional way as you have to think about how everything works and then create rules.
Continuing with the previous example, in the traditional way of programming, you have to
worry about whether the light switch icon is on the screen or not. Therefore, when you
return to the screen where this icon shows up, you have to check its status using the
viewDidAppear method. With reactive programming, you usually don't have to worry
about this.
When developing on iOS, you have to remember a few patterns, such as MVC, KVO, and
notifications, making the developer's life a bit complex as it is necessary to remember every
detail of each pattern. This can include unsubscribing the observer using the deinit
method. Reactive programming tries to merge these patterns and make everything work in
the same way.
In a nutshell, an application can have a lot of states. With traditional programming, you
have to be aware of all of these states, making development very complex and hard to
follow. Reactive programming creates a new approach where the developer doesn't need to
be worried about the complexity of states and their internal details; they just need to know
the main idea behind the application flow. Here's one definition of reactive programming: it
involves programming around data flows and the propagation of change.
This propagation of change is mainly based on two concepts, signals and streams, which
are going to be explained in the upcoming chapters.
[9]
In the 90s, design patterns were presented to the world in a book called Design Patterns,
written by the Gang of Four (Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides)
by Pearson. The idea behind these patterns was to create templates that could speed up
development and make software maintenance easier. An example of a famous design
pattern is (MVCModel-View-Controller (MVC).
The MVC pattern could also mean Massive View Controller; therefore, a new pattern had
to be created. Microsoft created a new pattern called Model-View-ViewModel (MVVM) in
the late noughties. This pattern was based on binding data with a view.
After MVVM was created, Microsoft created a framework called (RxReactive Extensions
(Rx). The idea behind this framework was to make it possible to perform reactive
programming with .NET mainly by propagating it with the changes made using LINQ. This
is the reason why searching for reactive programming on the Internet might take you to
some websites that use the following logo:
Nowadays, you can develop software using reactive programming in different languages;
for example, you can use ReactiveX and Rx.PHP if you develop on PHP, RxPY if you
develop on Python, or even Reflex if you develop on Perl.
Some frameworks are based on Rx and some are not. Before using a
specific reactive framework for your programming language, it is a good
idea to check its features and other users' opinions. Remember that
reactive programming is a relatively new programming concept; therefore,
some frameworks are still quite young.
[ 10 ]
Chapter 1
Now, let's create the equivalent code to this using the declarative programming approach.
Basically, we are going to use the map function to make the final code more readable:
var pricesVAT = [10, 8.1, 20.15].map { (element) -> Double in
return element * 1.2
}
In the preceding code, we just describe what we want to do, rather than how to do it, how
an array works, and so on.
If you've understood the difference between the code, remember that reactive programming
is a branch of declarative programming. This means that it can be simple for a new
developer or a bit hard for a developer who has been working with imperative
programming for a long time.
[ 11 ]
As you see, the value of variable c is 24. What happens to the value of variable c if we
change the value of a or b? The answer, as you know, is: it remains the same. Let's pretend
that our application has a shopping cart: variables a and b represent the prices of two
products and c is the amount to be paid. Variables a and b can change their value over
time: this can be due to a change in product, discount voucher, or some other reason. In
such a case, we have to remember to update the value of variable c, which can make
development a bit fragile.
Now, let's visualize this sample on a spreadsheet. Let's add value 9 to cell A1 and 15 to cell
B1. These cells, therefore, represent variables a and b from our previous code. Cell C1 has a
formula that represents the sum of A1 with B1, something that looks like this: C1=A1+B1.
Any changes made in A1 or B1 will automatically update the result of C1, and if any other
cells reference C1, they will also be updated. The following screenshot shows this example
in a visual way:
[ 12 ]
Chapter 1
After comparing the first code with this spreadsheet example, you can now understand
what dataflow is all about. Today's applications change values very frequently over a
period of time. This can be because a device has changed its state (it's lost a network
connection, for example), some information was received from the network, an animation
has finished, and so on. Each of these events may change the application's status and
update the UI.
Some people think that declarative programming has a lower rate of performance than
imperative programming, but the reality is a bit different. Let's perform some
benchmarking to check which one is faster. Create a new, single view project, and add the
following code to the viewDidLoad method:
override func viewDidLoad() {
super.viewDidLoad()
let array1:[Double] = [9,15.5, 3, 18, 7.9, 5.5, 2.2, 1.89, 995,
123.3, 4, 6.2, 12.12, 7,45, 6.61, 7.1, 2.9, 3.5, 52.1, 90, 82.2]
var array2:[Double]
let start = CFAbsoluteTimeGetCurrent()
array2 = [Double]()
for i in 0..<array1.count {
let element = array1[i] * 3.3
array2.append(element)
}
print(CFAbsoluteTimeGetCurrent() - start)
}
Execute this code, and take note of the execution time when it's in imperative mode. On a
MacBook Pro with a 2.6 GHz i5 processor, it took 0.000124990940093994 seconds. Now,
update the code to be a declarative one by replacing your current code with the highlighted
one:
override func viewDidLoad() {
super.viewDidLoad()
let array1:[Double] = [9,15.5, 3, 18, 7.9, 5.5, 2.2, 1.89, 995,
123.3, 4, 6.2, 12.12, 7,45, 6.61, 7.1, 2.9, 3.5, 52.1, 90, 82.2]
var array2:[Double]
let start = CFAbsoluteTimeGetCurrent()
array2 = array1.map({ (element) -> Double in
return element * 3.3
})
print(CFAbsoluteTimeGetCurrent() - start)
}
Execute the code again using the same simulator, and take note of the execution time. Using
the machine and simulator we saw previously, it took 0.0000889897346496582 seconds.
[ 13 ]
Why? The reason for this is that a declarative function might be optimized by the compiler
or built-in libraries, while when using an imperative function, you have to optimize
yourself.
This reasoning behind this is simple logic: if you compare the execution of a SQL SELECT
statement with code that's built from scratch you can think about which one has a better
performance. How long does the SELECT statement take to filter 50,000 records from a table
of 1,000,000 records? How long would it take if you had to write an equivalent filter using
imperative programming?
This code is a side effect, and this is what you have to try to avoid when using functional
programming; try to use more deterministic functions that don't use global variables.
Using methods, such as map (as we saw in a previous sample), reduce, sort, filter, and
other samples of functional programming, ensures that you send functions as arguments
and don't use external stuff.
To sum up, there are frameworks that are reactive but not based on functional
programming, and there are other frameworks, such as ReactiveCocoa, that are reactive and
functional.
[ 14 ]
Chapter 1
frequently. If you check the first Worldwide Developers Conference (WWDC) 2014 when
Swift was first announced, you will see a few features, such as the following ones, that are
out of date:
Some people say that Apple will stop supporting Objective-C soon or later, and other
people say that there will be features that are available only for Swift. This actually already
holds true for a protocol-oriented feature, for example. It doesn't matter whether these
rumors are true or not. It is very clear that Apple will be focusing more on Swift than
Objective-C from now on.
Keeping this fact in mind, take care when updating Xcode to ensure that the version of
ReactiveCocoa is compatible with the newest version of Swift. In case of compiler errors,
remember that you can always try to update your project and the ReactiveCocoa framework
by clicking on the Edit menu, opening the Convert option, and then selecting the To Latest
Swift Syntax submenu, as shown in the following screenshot:
If you have problems with ReactiveCocoa and the new version of Swift, first check whether
there is a new version of the framework before trying to fix it by yourself.
There are different ways to program with Swift; therefore, it is considered a multiparadigm
programming language. FRP with Swift requires knowledge about closures more than
using a target-action pattern, which is based on the selector of object methods.
[ 16 ]
Chapter 1
This project was started in March 2012 by Josh Abernathy. As Swift did not exist at the time,
it was developed for Objective-C. After the popularity of the Swift programming language,
a new branch was created and ReactiveCocoa was then ported to Swift. When the process
was completed, version 3.0 of ReactiveCocoa was released with Swift as its main language.
If you still have projects that use Objective-C and you would like to use ReactiveCocoa,
don't worry: you can still do this as Swift and Objective-C can exchange calls between each
other. You can read more about this bridging at https://github.com/ReactiveCocoa/R
eactiveCocoa/blob/master/Documentation/ObjectiveCBridging.md.
[ 17 ]
An alternative to using ReactiveCocoa is RxSwift. The main difference between them is that
RxSwift was a port of Microsoft Rx to the Swift programming language. ReactiveCocoa was
inspired by Rx; however, it is an independent project, and the idea does not revolve around
the porting of Rx.
ReactiveCocoa extensions
Is ReactiveCocoa alone? No, it is not. Today, there are many frameworks that are based on
ReactiveCocoa; thus, you don't have to worry about whether the required frameworks are
compatible with ReactiveCocoa. They are probably third-party extensions of your
frameworks already.
In Chapter 5, Enhance Your Application Using RAC Extensions, you will learn how to
use ReactiveCoreData (RCD), a framework that combines Core Data with ReactiveCocoa;
however, this is not the only framework that's based on the idea behind ReactiveCocoa.
Here are a few frameworks that are based on ReactiveCocoa.
ReactiveCocoaLayout (RCL): This describes a way of creating layouts with code
in a reactive way. This project is still in the alpha phase, and some people have
complained that everything you do is based on code, not on Interface Builder
(IB). However, for people who think that code is everything, it might be a great
solution. Check out this project at https://github.com/ReactiveCocoa/Rea
ctiveCocoaLayout.
ReactiveAnimation: This is a framework to create animations for iOS and OS X.
You will find a good example of it for Mac. For more information on this
framework, visit https://github.com/ReactiveCocoa/ReactiveAnimatio
n.
ReactiveCocoaIO: This is a file manager that's based on reactive programming.
This framework replaces NSFileManager, and because it works in an
asynchronous way, it is supposed to be faster. For more information on this
framework, take a look at https://github.com/ReactiveCocoa/ReactiveCo
coaIO.
Migrating to ReactiveCocoa
A question you might ask yourself is, How painful is it to migrate to ReactiveCocoa?
This, of course, depends on the size of your project, its complexity, structure, and and so on;
however, there are some rules that you can follow to make it easier.
[ 18 ]
Chapter 1
The process of converting an application code into an application that's developed with
ReactiveCocoa is called RACify. This process has no restrictive rule. What you have are
some steps that you can follow to create the right type of signal or stream.
We are going to learn more about this process in Chapter 7, Testing Your Application,
where we are going to take a framework and convert it into one that uses ReactiveCocoa.
[ 19 ]
This new concept, as you can imagine, works very asynchronously. You can try it out for
yourself using the HomeKit framework. This type of development can be controlled
through a simple application; however, when it progresses into becoming a complex
application, you might need a better methodology in place. Reactive programming is
considered the perfect framework for developing this kind of an application.
Health sensors may also be the next generation of new sensors on devices. The Apple
Watch already comes with a heartbeat sensor, which submits information to your phone,
and you can access it through the HealthKit. This information can also be accessed
asynchronously, especially if you can compare it with data on the Internet.
A health application is a good example of an application that can be used with reactive
programming. Every time, a user's health information changes, the application reacts in a
different way, displaying accurate diagnostics:
What about learning? Or better yet, e-learning? Believe it or not, there will come a time
when we will have to explain to our children that when we were young, we had to
physically go to school. Imagine an application that teaches you how to play the piano at
home with other remote students. In such a case, many asynchronous calls can be made:
when you press or release a key on your piano, signals are sent to your device while it
synchronizes with other students and the individual scores.
[ 20 ]
Chapter 1
Summary
In this chapter, we learned what functional reactive programming is, where it comes from,
and the advantages of using it. Now, you can appreciate that this new paradigm has had a
long history, but it started out as a mature concept not too long ago.
This type of programming paradigm is trending these days as it fits the needs of the
applications of today. This also makes the jobs of developers a lot easier easier.
Now that you have a better idea about reactive programming and ReactiveCocoa, be
prepared because we are going to start working with the two. Don't worry if you think that
some concepts look different because actually they are.
[ 21 ]
www.PacktPub.com
Stay Connected: