19
An Introduction to Reactive Cocoa Ara Hacopian BohConf July 2013

An Introduction to Reactive Cocoa

Embed Size (px)

DESCRIPTION

An intro to Reactive Cocoa from SmartLogic's Ara Hacopian.

Citation preview

Page 1: An Introduction to Reactive Cocoa

An Introduction to Reactive Cocoa

Ara Hacopian

BohConfJuly 2013

Page 3: An Introduction to Reactive Cocoa

What is Reactive Cocoa?

RAC is an Objective-C framework for Functional Reactive Programming

Page 4: An Introduction to Reactive Cocoa

Reactive Programming?

A programming paradigm oriented around data flows and propagation of change.

Page 5: An Introduction to Reactive Cocoa

Imperative

int x, y = 1, z = 1;

x = y + z; // x = 2; y = 1; z = 1;y = 3; // x = 2; y = 3; z = 1;NSLog(@"%d", x); // "2"

Page 6: An Introduction to Reactive Cocoa

Reactive

int x, y = 1, z = 1;

x = y + z; // x = 2; y = 1; z = 1;y = 3; // x = 4; y = 3; z = 1;NSLog(@"%d", x); // "4"

Page 7: An Introduction to Reactive Cocoa

We have this: KVO// In your viewDidLoad/awakeFromNib/init[self addObserver:self forKeyPath: @"someString" options:NSKeyValueObservingOptionNew context:&someStringChangeContext];

// In dealloc[self removeObserver:self forKeyPath: @"someString" context:&someStringChangeContext];

// Elsewhere in your class- (void)observeValueForKeyPath:( NSString *)keyPath ofObject:( id)object change:( NSDictionary *)change context:( void *)context{ if (context == &someStringChangeContext) { if ([keyPath isEqualToString: @"someString"]) { // Do a bunch of stuff here } }}

Page 8: An Introduction to Reactive Cocoa

Do it in RAC[RACAble(self.someString) distinctUntilChanged]

subscribeNext:^(NSString *string) { // Do a bunch of things here, just like you would with KVO}];

Source: http://tonyarnold.me/post/reactivelessons

Page 9: An Introduction to Reactive Cocoa

StreamsA series of object values.

● Accessed sequentially.● Available immediately or in the future.● Allow for declarative transforms

Two types:1. Signals2. Sequences

Page 10: An Introduction to Reactive Cocoa

SequenceA pull-driven stream.

● Lazily evaluated collections

Page 11: An Introduction to Reactive Cocoa

Sequence Example// words = @[ NSArray containing words ]

RACSequence *normalizedLongWords = [[words.rac_sequence

filter:^ BOOL (NSString *word) {return [word length] >= 10;

}]map:^(NSString *word) {

return [word lowercaseString];}];

Page 12: An Introduction to Reactive Cocoa

SignalA push-driven stream.

● Generally represents data that will be delivered in the future.

● Values are sent on the signal● Users subscribe to access values

3 types of events sent to subscribers:1. Next - provides next value2. Error3. Completed

Page 13: An Introduction to Reactive Cocoa

Signal Example[self.textField.rac_textSignal

subscribeNext:^(NSString *value) {NSLog(@"Text field updated: %@",

value);}];

Page 14: An Introduction to Reactive Cocoa

Signal Example 2

[[self.textField.rac_textSignal

filter:^BOOL(NSString *value) {return [value length] >= 3;

}]

subscribeNext:^(NSString *value) {NSLog(@"Text field updated: %@",

value);}];

Page 15: An Introduction to Reactive Cocoa
Page 16: An Introduction to Reactive Cocoa

RACSignal *formValid = [RACSignalcombineLatest:@[

self.userNameField.rac_textSignal,self.emailField.rac_textSignal,self.confirmEmailField.rac_textSignal,

]reduce:^(NSString *userName, NSString *email,

NSString *confirmEmail) {return @(username.length > 0

&& email.length > 0 && confirmEmail.length > 0 && [email isEqualToString:confirmEmail]);

}];

RAC(self.createAccountBtn.enabled) = formValid;

Page 17: An Introduction to Reactive Cocoa

RACCommandself.loginCommand = [RACCommand command]; self.loginSignals = [self.loginCommand

addSignalBlock:^(id sender) {return [client logIn];

}];[self.loginSignals subscribeNext:^(RACSignal

*loginSignal) {[loginSignal subscribeCompleted:^(id _) {

NSLog(@"Logged in successfully!");}];

}];self.loginBtn.rac_command = self.loginCommand;