Active Filters: ReactiveCocoa

Today we'll take our first look at ReactiveCocoa. It's a huge topic, so we'll start with why we might want to use it. Let's dive in. 🏊

Traditionally, we'd wire up the different components in our app declaratively. We'd use common Cocoa techniques like Delegates, KVO, NSNotificationCenter notifications, target/actions, etc.

At first our app might have just a text field and delegate. But then we add a button, and maybe a segmented control. Things can quickly get messy. We inevitably end up with code like this sprinkled throughout our view controllers:

if crewNameIsValid && crewRankIsValid && !ship.full {
  createButton.enabled = true
} else {
  createButton.enabled = false
}

We're also using a ton of different mechanisms to accomplish the same conceptual task: Updating our UI to reflect state changes. Managing all of this in a small app might not seem like a big issue, but in even moderately complex codebases, this can be a big source of bugs. 🐞

Enter ReactiveCocoa (also commonly called "RAC"). It's a library for iOS and OS X that helps us write code that works with streams of values over time. It also allows us to write code that's closer to how we think about our app while building it:

"The Create Crew Member button should only be enabled: if the crew name is valid, and a rank has been selected, and the ship is not already full."

For example, in RAC, we can get a reference to a signal producer, which will send along our field's text, every time it changes:

let crewNameValid = crewNameTextField
  .rac_textSignal()
  .toSignalProducer()
  .map { $0 as! String }

crewNameValid.startWithNext { text in /* do something with text */ }

We'll do this for our rank control too. Next, we can merge both of these signal producers into one, then use the values that signal producer sends along to set our createButton's enabled property.

let formValidSignal = zip(crewNameValid, crewRankValid).map { $0 && $1 }

ReactiveCocoa is a giant departure from how we've traditionally built our apps. Don't worry if it doesn't make sense right away. In the future, we'll dive deeper into RAC, and look at all the different ways we can use it.

More info about ReactiveCocoa can be found at git.io/RAC