ReactiveCocoa
Werner Ramaekers
Jan Sabbe
Cocoaheads BE
12/03/2014
ReactiveCocoa (RAC) 
is an Objective-C framework for 
Functional Reactive
Programming.

It provides APIs for composing
and...
Whut ?
Programming
PIN OUT
Take inputs Produce outputs
Imperative programming
•int x; int y = 1; int z = 2;
•x = y + z; //x == 3; y == 1; z == 2;
!
PIN OUT
Imperative programming
•int x; int y = 1; int z = 2;
•x = y + z; //x == 3; y == 1; z == 2;
!
PIN OUT
•y = 2;
•NSLog(@“%i”,...
Imperative programming
•int x; int y = 1; int z = 2;
•x = y + z; //x == 3; y == 1; z == 2;
!
PIN OUT
STATE•y = 2;
•NSLog(@...
Declaractive programming
•The developer describes the problem
domain in a declarative way, 
!
•The focus is NOT on state
!...
Functional Programming
•is one way of declarative programming.
!
•Functional programming..
•deemphasizes state & mutable d...
Reactive Programming
•also is a way of declarative
programming
!
•Reactive Programming ..
•dynamically links the program’s...
Reactive Programming
•also is a way of declarative
programming
!
•Reactive Programming ..
•dynamically links the program’s...
Functional Reactive Programming
•.. combines the FUNCTIONAL and
REACTIVE programming styles.
!
•.. links functions that ob...
ReactiveCocoa (RAC) 
is an Objective-C framework for 
Functional Reactive
Programming.

It provides APIs for composing
and...
RAC : ReActiveCocoa
Stream Subscriber
RACStream produces a Stream existing of …
RAC : ReActiveCocoa
Stream
Next Event
Subscriber
RACStream produces a Stream existing of …
RAC : ReActiveCocoa
Stream
Next Event
Complete Event
Subscriber
RACStream produces a Stream existing of …
RAC : ReActiveCocoa
Stream
Next Event
Complete Event
Subscriber
Error Event
RACStream produces a Stream existing of …
RAC : ReActiveCocoa
Stream Subscriber
[ 1, 2, 3]
RACSequence
RAC : ReActiveCocoa
Stream Subscriber
[ 1, 2, 3]
123
RACSequence
RAC : ReActiveCocoa
Stream Subscriber
RACSignal
Client Server
RAC : ReActiveCocoa
Stream Subscriber…
JSON
RACSignal
Client Server
RAC : ReActiveCocoa
Stream Subscriber…
∞
RACSignal
Client
listen
RAC : ReActiveCocoa
RACStream
RACSignal RACSequence
ReactiveCocoa
•RACStream
•abstract class
•represents some sequential flow of data
•RACSignal (cold)
•push-driven data strea...
Details please
RACSignal
!
[self.textField.rac_textSignal subscribeNext:^(id x) {
NSLog(@“New value : %@“, x);
} error:^(NSError *error){...
RACSignal
!
[self.textField.rac_textSignal subscribeNext:^(id x) {
NSLog(@“New value : %@“, x);
!
!
!
!
}];
RACSignal : combineLatest
123
C.L.
( )=,
RACStream operators
•Simplifies transformations of streams into
new streams
•map, filter, fold/reduce
!
RACStream : map
MAP =
( ) =
RACSequence *stream = [@[@(1), @(2), @(3)] rac_sequence];
[stream map:^id(id value) {
return @...
RACStream : flatten map
FMAP =
( ) =
Function result = stream
RACStream : filter
RACSequence *stream = [@[@(1), @(2), @(3)]; rac_sequence];
NSLog(@“%@“,
[[[array rac_sequence] filter:^B...
Validating input the “old” way
#pragma mark - UITextFieldDelegate
!
- (BOOL) textField:(UITextField *)textField
shouldChan...
Validating input the “old” way
#pragma mark - UITextFieldDelegate
!
- (BOOL) textField:(UITextField *)textField
shouldChan...
Validating input the “RAC” way
RAC(self.createButton, enabled) =
!
[RACSignal combineLatest:@[
self.usernameTF.rac_textSig...
Validating input the “RAC” way
RAC(self.createButton, enabled) =
!
[RACSignal combineLatest:@[
self.usernameTF.rac_textSig...
“not so fast cowboy .. “
•RAC(object, key path) is a macro
•creates a one-way binding
•ex. bind “enabled” property of a UI...
Now, show me a real app
Station locator app
Station locator app
Station locator app
Station locator app
Core Data
Stations
GPS coord
Services
Prices
Station locator app
Core Data
Stations
GPS coord
Services
Prices
Driving 
distance
Station locator app
Prices.xml
Core Data
Stations
GPS coord
Services
Prices
Driving 
distance
Station locator app
Stations.xml Prices.xml
Core Data
Stations
GPS coord
Services
Prices
Driving 
distance
Easier asynchronous code
Driving 
distance
1
2
3 Core Data lookup in Background
current location
RAC( ) = (51.2, 5.46)
station (id=4)
flattenMap 

searchClosest(51.2,5.46)
flattenMap 

getDrivingDistance(4)
JSON
map 

JSO...
Sort stations by driving distance
station (id=1)
station (id=3)
station (id=2)
getDrivingDistance
combineLatest 

sort [3,...
MVC
MVC
Scott, 
how do we test
UIViewControllers
ViewModel pattern
ViewController

sets up binding

animations
ViewModel

(BOOL) shop

(BOOL) bread

(RACCommand) search
Se...
ViewModel pattern
ViewController

sets up binding

animations
ViewModel

(BOOL) shop

(BOOL) bread

(RACCommand) search
Se...
ViewModel pattern
ViewController

sets up binding

animations
ViewModel

(BOOL) shop

(BOOL) bread

(RACCommand) search
Se...
RACCommand
while getting current location, searching stations, sort by driving distance,... show activity indicator
[[RACC...
RACCommand
while getting current location, searching stations, sort by driving distance,... show activity indicator
[[RACC...
ReactiveCocoa …
•keeps the app focused on representing data
& UX
•can reduce complexity bc you don’t need to
worry about ‘...
but ReactiveCocoa …
•introduces another way of thinking.
•adds another learning curve on top of
Cocoa
!
•is a framework by...
One last thing
Thank you
ReactiveCocoa (RAC): Functional Reactive Programming
ReactiveCocoa (RAC): Functional Reactive Programming
ReactiveCocoa (RAC): Functional Reactive Programming
ReactiveCocoa (RAC): Functional Reactive Programming
Upcoming SlideShare
Loading in …5
×

ReactiveCocoa (RAC): Functional Reactive Programming

3,930 views

Published on

In this presentation, Werner Ramaekers and Jan Sabbe provide an introduction to ReactiveCocoa.

Published in: Technology
0 Comments
16 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,930
On SlideShare
0
From Embeds
0
Number of Embeds
1,154
Actions
Shares
0
Downloads
47
Comments
0
Likes
16
Embeds 0
No embeds

No notes for slide

ReactiveCocoa (RAC): Functional Reactive Programming

  1. 1. ReactiveCocoa Werner Ramaekers Jan Sabbe Cocoaheads BE 12/03/2014
  2. 2. ReactiveCocoa (RAC) is an Objective-C framework for Functional Reactive Programming. It provides APIs for composing and transforming streams of values.
  3. 3. Whut ?
  4. 4. Programming PIN OUT Take inputs Produce outputs
  5. 5. Imperative programming •int x; int y = 1; int z = 2; •x = y + z; //x == 3; y == 1; z == 2; ! PIN OUT
  6. 6. Imperative programming •int x; int y = 1; int z = 2; •x = y + z; //x == 3; y == 1; z == 2; ! PIN OUT •y = 2; •NSLog(@“%i”, x); //-> ‘3’ ! # Input changed but output did NOT because it was declared earlier….
  7. 7. Imperative programming •int x; int y = 1; int z = 2; •x = y + z; //x == 3; y == 1; z == 2; ! PIN OUT STATE•y = 2; •NSLog(@“%i”, x); //-> ‘3’ ! # Input changed but output did NOT because it was declared earlier….
  8. 8. Declaractive programming •The developer describes the problem domain in a declarative way, ! •The focus is NOT on state ! •Focus is on : •data flow •propagation of change
  9. 9. Functional Programming •is one way of declarative programming. ! •Functional programming.. •deemphasizes state & mutable data •emphasizes functions that produce outputs based on inputs : z = f(x, y) PIN OUT
  10. 10. Reactive Programming •also is a way of declarative programming ! •Reactive Programming .. •dynamically links the program’s behaviour to its continuously updating data stream PIN OUT
  11. 11. Reactive Programming •also is a way of declarative programming ! •Reactive Programming .. •dynamically links the program’s behaviour to its continuously updating data stream PIN OUT •E.g. : a spreadsheet application where •cell A1 (= B1 + C1)
  12. 12. Functional Reactive Programming •.. combines the FUNCTIONAL and REACTIVE programming styles. ! •.. links functions that observe continuous and dynamic streams of data (inputs) to the program’s behaviour (outputs) in real time.
  13. 13. ReactiveCocoa (RAC) is an Objective-C framework for Functional Reactive Programming. It provides APIs for composing and transforming streams of values.
  14. 14. RAC : ReActiveCocoa Stream Subscriber RACStream produces a Stream existing of …
  15. 15. RAC : ReActiveCocoa Stream Next Event Subscriber RACStream produces a Stream existing of …
  16. 16. RAC : ReActiveCocoa Stream Next Event Complete Event Subscriber RACStream produces a Stream existing of …
  17. 17. RAC : ReActiveCocoa Stream Next Event Complete Event Subscriber Error Event RACStream produces a Stream existing of …
  18. 18. RAC : ReActiveCocoa Stream Subscriber [ 1, 2, 3] RACSequence
  19. 19. RAC : ReActiveCocoa Stream Subscriber [ 1, 2, 3] 123 RACSequence
  20. 20. RAC : ReActiveCocoa Stream Subscriber RACSignal Client Server
  21. 21. RAC : ReActiveCocoa Stream Subscriber… JSON RACSignal Client Server
  22. 22. RAC : ReActiveCocoa Stream Subscriber… ∞ RACSignal Client listen
  23. 23. RAC : ReActiveCocoa RACStream RACSignal RACSequence
  24. 24. ReactiveCocoa •RACStream •abstract class •represents some sequential flow of data •RACSignal (cold) •push-driven data stream of future values •cfr Network call •must be subscribed to in order to access data •RACSequence •pull-driven data stream •similar to Cocoa collection classes (NSArray, ..) •but values are evaluated lazily - only when needed
  25. 25. Details please
  26. 26. RACSignal ! [self.textField.rac_textSignal subscribeNext:^(id x) { NSLog(@“New value : %@“, x); } error:^(NSError *error){ NSLog(@“Error : %@“, error); } completed:^{ NSLog(@“That’s all folks !”); }];
  27. 27. RACSignal ! [self.textField.rac_textSignal subscribeNext:^(id x) { NSLog(@“New value : %@“, x); ! ! ! ! }];
  28. 28. RACSignal : combineLatest 123 C.L. ( )=,
  29. 29. RACStream operators •Simplifies transformations of streams into new streams •map, filter, fold/reduce !
  30. 30. RACStream : map MAP = ( ) = RACSequence *stream = [@[@(1), @(2), @(3)] rac_sequence]; [stream map:^id(id value) { return @(pow([value integerValue], 2)); }]; NSLog(@“%@“, [stream array]);
  31. 31. RACStream : flatten map FMAP = ( ) = Function result = stream
  32. 32. RACStream : filter RACSequence *stream = [@[@(1), @(2), @(3)]; rac_sequence]; NSLog(@“%@“, [[[array rac_sequence] filter:^BOOL(id value){ return [value integerValue] % 2 == 0; }] array] ); Filter = ( ) = True ?
  33. 33. Validating input the “old” way #pragma mark - UITextFieldDelegate ! - (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { self.createButton.enabled = [self isFormValid]; ! return YES; }
  34. 34. Validating input the “old” way #pragma mark - UITextFieldDelegate ! - (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { self.createButton.enabled = [self isFormValid]; ! return YES; } - (BOOL)isFormValid { return [self.usernameField.text length] > 0 && [self.emailField.text length] > 0 && [self.passwordField.text length] > 0 && [self.passwordField.text isEqual:self.passwordVerificationField.text]; } … …… …
  35. 35. Validating input the “RAC” way RAC(self.createButton, enabled) = ! [RACSignal combineLatest:@[ self.usernameTF.rac_textSignal, self.emailFieldTF.rac_textSignal, self.passwordFieldTF.rac_textSignal, self.passwordVerificationFieldTF.rac_textSignal ] reduce:^(NSString *username, NSString *email, NSString *password, NSString *passwordVerification) { return @([username length] > 0 && [email length] > 0 && [password length] > 8 && [password isEqual:passwordVerification]); }];
  36. 36. Validating input the “RAC” way RAC(self.createButton, enabled) = ! [RACSignal combineLatest:@[ self.usernameTF.rac_textSignal, self.emailFieldTF.rac_textSignal, self.passwordFieldTF.rac_textSignal, self.passwordVerificationFieldTF.rac_textSignal ] reduce:^(NSString *username, NSString *email, NSString *password, NSString *passwordVerification) { return @([username length] > 0 && [email length] > 0 && [password length] > 8 && [password isEqual:passwordVerification]); }];
  37. 37. “not so fast cowboy .. “ •RAC(object, key path) is a macro •creates a one-way binding •ex. bind “enabled” property of a UIButton to a signal
  38. 38. Now, show me a real app
  39. 39. Station locator app
  40. 40. Station locator app
  41. 41. Station locator app
  42. 42. Station locator app Core Data Stations GPS coord Services Prices
  43. 43. Station locator app Core Data Stations GPS coord Services Prices Driving distance
  44. 44. Station locator app Prices.xml Core Data Stations GPS coord Services Prices Driving distance
  45. 45. Station locator app Stations.xml Prices.xml Core Data Stations GPS coord Services Prices Driving distance
  46. 46. Easier asynchronous code Driving distance 1 2 3 Core Data lookup in Background current location
  47. 47. RAC( ) = (51.2, 5.46) station (id=4) flattenMap 
 searchClosest(51.2,5.46) flattenMap 
 getDrivingDistance(4) JSON map 
 JSON -> km "4.5 km"
  48. 48. Sort stations by driving distance station (id=1) station (id=3) station (id=2) getDrivingDistance combineLatest 
 sort [3,1,2] fetching driving distances concurrently when all available, sort
  49. 49. MVC
  50. 50. MVC
  51. 51. Scott, how do we test UIViewControllers
  52. 52. ViewModel pattern ViewController
 sets up binding
 animations ViewModel
 (BOOL) shop
 (BOOL) bread
 (RACCommand) search SearchService
 (RACSignal) searchWithCriteria validates + delegate to service do actual search
  53. 53. ViewModel pattern ViewController
 sets up binding
 animations ViewModel
 (BOOL) shop
 (BOOL) bread
 (RACCommand) search SearchService
 (RACSignal) searchWithCriteria mock out the real search service do search against in memory DB easily testable harder to test hard to test but trivial
  54. 54. ViewModel pattern ViewController
 sets up binding
 animations ViewModel
 (BOOL) shop
 (BOOL) bread
 (RACCommand) search SearchService
 (RACSignal) searchWithCriteria validates + delegate to service do actual search what is this?
  55. 55. RACCommand while getting current location, searching stations, sort by driving distance,... show activity indicator [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id sender) { return [self createSearchSignal]; }]; ViewModel
  56. 56. RACCommand while getting current location, searching stations, sort by driving distance,... show activity indicator [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id sender) { return [self createSearchSignal]; }]; ViewModel ViewController self.searchButton.rac_command = self.viewModel.searchCommand; RAC(self, spinner.hidden) = [self.viewModel.searchCommand.executing not];
  57. 57. ReactiveCocoa … •keeps the app focused on representing data & UX •can reduce complexity bc you don’t need to worry about ‘state’ so much •keeps related code close together (via blocks) •helps to make your code more testable (via MVVM)
  58. 58. but ReactiveCocoa … •introduces another way of thinking. •adds another learning curve on top of Cocoa ! •is a framework by GitHub and not Apple ! •will Apple "sherlock" ReactiveCocoa ?
  59. 59. One last thing
  60. 60. Thank you

×