Download - Reactive Cocoa
Reactive CocoaRobert Brown Twitter: @robby_brown ADN: @robert_brown
What is Reactive Cocoa?
A framework for Functional Reactive Programing (FRP)
Developed by GitHub
What is Functional Reactive Programming?
–Wikipedia
“Functional reactive programming (FRP) is a programming paradigm for reactive programming
using the building blocks of functional programming.”
What are the building blocks of functional programming?
!
reduce/fold
map
filter
zip
!
drop
take
concat
and more
What is functional programming?
Immutable data
Limited state
Pure functions
Immutable Data
Data structures can’t be modified in place
Values are copied as needed
NSArray vs. NSMutableArray
Limited State
No global data
No side effects
Pure Functions
Given input X, the function always returns Y
Allows for many compiler-level optimizations
Higher Order Functions
Map
1
2
3
2
4
6
x * 2
5
6
7
x + 4
Reduce / Fold
1
2
3
0
Sum
136
How do I use Reactive Cocoa?
RACSignal
RACSignal is a stream of data, possibly infinite
Its values are evaluated lazily
Signals are the most used objects in Reactive Cocoa
RAC as KVO
Advantages:
No more hard-coded key paths
No more comparing key paths
Code locality
Refactoring will update RAC bindings
RAC as KVO
Disadvantages:
Watch out for retain cycles
All objects are of type id
RAC as KVO
[RACObserve(self, name) subscribeNext:
^(NSString * name) {
NSLog(@“Name changed: %@”, name);
}];
RAC Bindings
Like Cocoa Bindings
Automatically changes properties
RAC Bindings
RAC(self, textField2.text) = self.textField1.rac_textSignal;
!
RAC(self, nameField.text) = RACObserve(self, name);
Tips and Tricks
Transform the values of a signal:
[signal map:^id(NSString * text) {
return [text uppercaseString];
}];
Tips and TricksCombine the results of many signals:
[RACSignal combineLatest:@[s1, s2] reduce:
^id(NSNumber * b1, NSNumber * b2) {
return @([b1 boolValue] &&
[b2 boolValue]);
}];
Tips and Tricks
Watch for when multiple tasks complete:
[[RACSignal merge:@[signal1, signal2] subscribeCompleted:^{
NSLog(@“All done”);
}];
Tips and TricksAdd actions to buttons:
self.button.rac_command =
[[RACCommand alloc] initWithSignalBlock:^RACSignal *(id x) {
// Code goes here
};
Tips and TricksCreate arbitrary signals:
[RACSignal createSignal:
^RACDisposable *(id<RACSubscriber> subscriber) {
// Send next, error, and completed
// messages to subscriber
}];
Tips and Tricks
Deliver signal results to the main thread:
[backgroundSignal deliverOn:
[RACScheduler mainThreadScheduler]];
Tips and Tricks
If you need to perform side effects:
[signal doNext:^(id value) {…}];
[signal doError:^(NSError * error) {…}];
[signal doCompleted:^{…}];
Tips and Tricks
Limit the rate a signal can be evaluated:
[signal throttle:10.0];
Questions?
Demo
Want to Learn More?
GitHub
NSHipster
Ray Wenderlich
Other Implementations
C♯ Reactive Extensions (Rx)
JavaScript react.js