Chapters

Hide chapters

Expert Swift

Second Edition · iOS 18.5 · Swift 6.1 · Xcode 16.3

11. Functional Reactive Programming
Written by Ehab Amer

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

As a developer, you probably bump into buzzwords daily. Some of the most popular and frequently recurring of these are probably “reactive programming”, “functional programming” or even “functional reactive programming”.

Like many other buzzwords, these terms describe a vast family of programming concepts and practices, often confusing and deterring developers.

This chapter will focus on the most important and refined concepts of functional reactive programming and how you can apply these concepts to your apps.

Functional? Reactive?

Although these terms are often used together, they’re not mutually inclusive. This means that each term stands by itself.

Reactive programming

The idea of reactive programming is that instead of manually and imperatively reading the state or value of some entity, you listen, or subscribe, to changes of that entity and get notified whenever your state changes — in which case, you can react to the change and update your app accordingly. These changes are emitted over time:

yufukKgile 5 5.4 63 29 Mowix $47 Reyob $11 Dorip $8.1 Gimum $7

adunLinaxce 5 48 hjeyiywGmetu 37 15 norXonoZixtvoha ciybi lhui

Functional programming

Functional programming, unsurprisingly, revolves around functions, but more specifically pure functions.

Why not both?

So why are these terms put together so often, you might ask? It’s simply because functional programming concepts are inherent in most use cases of reactive programming.

7 7 3 dop { $7 * 4 } 1 5 6

Reactive basics

There are many attempts at defining a unified standard for how streams behave. The most common ones are Reactive Streams (https://www.reactive-streams.org/) and Reactive Extensions (Rx) (http://reactivex.io/). In essence, all these different standards and their implementations share the same base concepts.

Naming

The basic streams, or producers, that emit updates to subscribers have different naming across implementations. For example, in RxSwift they’re called Observables, while in Combine they’re called Publishers.

Events

These producers emit not only values, but something called an event.

Offukoza zwaig hggiat, yuyin sumgqopav Piunaow plceaj, ijgy nuxc xizwwiyuum Tzpurz jrxooh, etbt rupy meeloka 4 0.7 77 35 qikxi bigdu ccei rehpu eip ubx asu bol

Thinking of water

Streams of data are analogous to streams of water. Think of a complex system of pipes, where you may open each tap as much as you’d like and have all different sources of water (streams) drain into a single sink (the consumer). You may also close a specific tap (canceling the subscription to that stream).

Streams are just supercharged sequences

When you look at streams and the Swift language, where can you draw a parallel between them? The answer is simple: Sequences or, more broadly, Iterators.

The Luthier app

It’s time to get practical and write some code. From this point forward, you’ll use a specific reactive implementation instead of general reactive ideas. In this case, Combine is the obvious and easy choice because it’s readily available as part of Apple’s SDK.

Exploring the project

Open the starter project. Here’s an overview of its structure and what it includes:

Building a guitar

Build and run the starter project, and you’ll notice a preview of the base model guitar along with a dummy “Checkout” button. Nothing too fancy:

Your first View Model

The view model is the central hub for each of your views. It gets everything the user does and selects as input, and provides the latest state for the view to draw as output. You’ll start with making sure you have all the inputs, first.

Adding guitar addition pickers

Back in BuildView.swift, you’ll find a handy helper method called additionPicker(for:selection:), which takes an addition type and a binding to track the user’s selection.

Constructing a Guitar object

Right now, your GuitarView uses a hardcoded Guitar instance, and you’ll notice that any changes to the pickers aren’t reflected in the view. It’s time to change that!

Using your reactive guitar

To see this in action, go back to BuildView.swift and replace the dummy Guitar initializer in GuitarView with viewModel.guitar so it looks like this:

Subscription lifecycle

So far, so good. It seems viewModel.guitar is constantly emitting new Guitar updates based on your selection. But how can you confirm that’s the case?

Yahpvtenjoev gax vijsqbarciur ans orezbl timzdduculw ufwburilzf tejpiweyle of axrrosodpr qocfofok uk jeafwaxeteon Kiwnicqit en Laapux Paaz Tujoh (bujrvtutij)

Getting to checkout

The basic functionality of your build view is done, but you’re still missing a few more pieces to be able to move to checkout. Specifically, you’ll want to:

ekuatakadepr wciqe omcowoga lvalqijp ulvoufr Ujilr geccancu yhod axw xelaawyg Nmenmq ji Bnippeow axif gakh bzalyiuf apulimu ar tazeytaq

Triggering requests

First, you’ll need some way to tell the view model “The user tapped checkout” so you can react to that action and call the three API calls.

Checkout

As mentioned in the previous section, you’ll need to make three separate but parallel API calls to fetch all the data needed for the checkout screen.

Preparing your API calls

At the end of your initializer, add the following code to support the guitar availability call:

Connecting the pieces

Now that you have your publishers, it’s time to connect them and subscribe to their combined result. But what kind of composition are you looking for here?

Showing a loading indicator

Right now, the user can keep tapping the button endlessly. But worse, there’s no indication on the screen to let them know something’s being loaded. It’s time to fix that.

rulhabHgihmeet upuuxozexarj ulziyili cyinbebw tatbocku ayoopelonunr.san(ushikudi, qjeldewx) sseu gubti emNoajitxKfedmoaz

Pushing the result to Checkout

The last thing to do in BuildView is to use the response and navigate with it to your next view, CheckoutView.

Sharing resources

Your code works well right now, but there is a tiny (or yet, quite large) issue with it that is quite hidden.

pcifvoog egme huiqurg ptiqi 8 1 5 1 7 9 cifcomsa jahtahci (dagyoxaza)

cduyzook apjo fuikuby rxiga fudzujra 3 0 8

Wrapping up BuildView

All that’s left for you to do is to present CheckoutView in response to viewModel.checkoutInfo firing a value.

Performing Checkout

Your checkout view already includes a solid layout of the screen you’ll work on, displaying the guitar parts you chose in the previous step, the estimated build time and availability you calculated, as well as available shipping options.

Changing the order currency

In this section, you’ll add one rather large change. You’ll let the user pick one of several currencies to use for their order.

Setting up the view model

First things first: Go to CheckoutViewModel.swift and add the following @Published property to your “inputs”:

Taking currency into account

Instead of directly accessing the Guitar and ShippingOption prices, you’ll now react to currency changes and adjust these prices accordingly, deciding what string to show to the consumer and feeding those values to the published properties you added previously.

Connecting the view

Phew, that was a lot of code — congratulations for getting here! The portion you just worked on was where most of the work in this checkout view comes into play.

Tidying currency changes

This works quite nicely but misses a final touch.

Checking out

All that’s left to do is check out. Knock this one out of the park!

Key points

  • Reactive programming is the notion of publishing changes for a specific piece of state so your app can keep itself updated.
  • You can represent any kind of event, network request, resource or generally a piece of work as a reactive stream that emits changes about those resources.
  • Streams are inherently similar to iterators: Whereas streams push changes, iterators require pulling from them.
  • Many frameworks provide reactive capabilities for Swift developers. The most common ones are Combine, RxSwift and ReactiveSwift.
  • Combine is Apple’s reactive framework, which was introduced at WWDC 2020.
  • One of the huge superpowers of such frameworks is the composition of multiple publishers together as other publishers, using operators such as zip, combineLatest and merge.
  • You used many other extremely powerful operators in this chapter, such as flatMap, map and debounce. There are many others you still haven’t used, such as retry, throttle and more.
  • Reactive is what you make of it! Use it all over the place or take just as much as you need for a specific use case. It’s a tool at your disposal.
  • Although this chapter focused on SwiftUI and some SwiftUI-specific ideas, you can easily leverage the knowledge of this chapter in UIKit-based apps.

Where to go from here?

Wow, you’ve done such wonderful work in this chapter!

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now