Replacing Objective-C Delegate Pattern with ReactiveCocoa
An interesting article by Justin DeWind on "Replacing Objective-C Delegate Pattern with ReactiveCocoa". how to use ReactiveCocoa to replace and augment your existing delegate pattern, and modernise it with a more futuristic delegate pattern.
ReactiveCocoa is a library created by GitHub that brings “Functional Reactive Programming” to Objective-C. It provides a number useful features right out of the gate which gives a developer the power to observe, transform, merge, and filter signals that contain values.
More importantly, it has the power to build on top of and replace existing (and sometimes archaic) patterns used in Objective-C. One of the most common of these patterns is the “delegate pattern.”
The Delegate Pattern
The delegate pattern is a pattern of delegating tasks to an object and potentially informing it of certain actions that are being taken. Here’s a typical example of the delegate pattern found in iOS programming:
In this particular example, the object (presumably a UIViewController) is the delegate to both the
UISearchDisplayController. ThesearchBar:textDidChange: delegate method updates the search results and the UISearchDisplayController delegate methods (searchDisplayControllerDidBeginSearchand searchDisplayControllerDidEndSearch respectively) track whether the search is currently active.
There are a couple of issues with this delegate approach:
- There is only ever one object that can subscribe to changes to the
UISearchDisplayController. All actions must go through the delegate.
- The act of searching is is scattered across three different callbacks.
The ReactiveCocoa Toolbox
ReactiveCocoa has built-in helpers for creating signals from any
selectoron an object or protocol.
rac_signalForSelector: and rac_signalForSelector:fromProtocol:
These two helpers will create a signal that is bound to a selector, such that any time that selector is invoked on the object it will send a new value through the signal.
This helper will “lift” a selector into “signal space” where the selector is invoked anytime the corresponding argument signals send a new value. The signals passed to the
rac_liftSelectormust match the number of arguments expressed by the selector.
Replacing the Delegate Pattern
Now that we have familiarized ourselves with some of the more powerful aspects of ReactiveCocoa, we can replace the delegate pattern example with one that uses signals.
Instead of having to assign a delegate to the UISearchBar and implement
searchBar:textDidChange:, let’s modify the UISearchBar so there is a signal representing changes to the text.