Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ReactiveCocoa. Functional Reactive Programming ...

ReactiveCocoa. Functional Reactive Programming on Objective-C

A talk from CocoaHeads Moscow May'14 meeting (http://www.cocoaheads.ru).

Video available here: http://www.youtube.com/watch?v=DgdISd1Qc48

Dmitry Obukhov

May 30, 2014
Tweet

More Decks by Dmitry Obukhov

Other Decks in Programming

Transcript

  1. What Is RAC –Open-source framework by GitHub team –An implementation

    of FRP on iOS/OS X –Inspired by .NET’s RX ?
  2. Functional reactive programming (FRP) is a programming paradigm for reactive

    programming using the building blocks of functional programming. ł9KMKRGFKC “ ”
  3. Functional Programming – Evaluation of mathematical functions – Avoids state

    and mutable data – Results depend only on input arguments – Programming is done with expressions
  4. Reactive Programming – Focuses on data flow – A graph

    of signals that propagate change – Event-driven programming
  5. Signal –Stream of values –Sends events –next –error –completed [signal

    subscribeNext:^(id x) { NSLog(@"%@", x); } error:^(NSError *error) { // handle error } completed:^{ // done. }]; –Can have subscribers –Supports functional
 operations
  6. - (RACSignal *)rac_GET:(NSString *)path parameters:(NSDictionary *)parameters { return [RACSignal createSignal:^(id<RACSubscriber>

    subscriber) { NSURLSessionDataTask *task = [self GET:path parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) { [subscriber sendNext:responseObject]; [subscriber sendCompleted]; } failure:^(NSURLSessionDataTask *task, NSError *error) { [subscriber sentError:error]; }]; ! return [RACDisposable disposableWithBlock:^{ [task cancel]; }]; }]; } ! ... ! [[self.sessionManager rac_GET:@"posts" parameters:@{@"author": @"stel"}] subscribeNext:^(Post *post) { [self displayPost:post]; } error:^(NSError *error) { [self presentError:error]; }]; Create signals
  7. Sequences NSMutableArray *tmp = [NSMutableArray array]; ! for (NSString *str

    in strings) { if (str.length < 2) { continue; } ! NSString *newString = [str stringByAppendingString:@"foobar"]; ! [tmp addObject:newString]; } ! NSArray *results = [NSArray arrayWithArray:tmp];
  8. Sequences NSArray *results = [[strings.rac_sequence filter:^BOOL(NSString *str) { return str.length

    >= 2; }] map:^(NSString *str) { return [str stringByAppendingString:@"foobar"]; }] array]; Manipulate any Cocoa collection in a uniform and declarative way
  9. Observers [self.user addObserver:self forKeyPath:@"username" options:NSKeyValueObservingOptionNew context:NULL]; ! ! - (void)observeValueForKeyPath:(NSString

    *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (object == self.user) { if ([keyPath isEqualToString:@"username"]) { ... } } else if (...) { ... } }
  10. Observers [RACObserve(self.user, username) subscribeNext:^(id x) { ... }]; [[RACObserve(self.user, username)

    filter:^BOOL(NSString *string) { return [string hasPrefix:@"s"]; }] subscribeNext:^(id x) { ... }];
  11. Bindings RAC(self, createEnabled) = [RACSignal combineLatest:@[RACObserve(self, password), RACObserve(self, passwordConfirmation)] reduce:^(NSString

    *password, NSString *confirmation) { return @([confirmation isEqualToString:password]); }]; RAC(self, password) = self.passwordTextField.rac_textSignal; ! ... ! RAC(self.createButton, enabled) = RACObserve(self, createEnabled);
  12. Commands RACCommand *command = [[RACCommand alloc] initWithEnabled:enabledSignal signalBlock:^RACSignal *(id input)

    { return [[[HTTPClient downloadTonsOfDataWithID:dataID] takeUntil:cancelCommand.executing] doNext:^(NSData *data) { [data writeToURL:localURL atomically:YES]; }]; }]; ! self.downloadButton.rac_command = command;
  13. Schedulers RAC(self.imageView, image) = [[[[HTTPClient fetchUserWithUsername:@"stel"] deliverOn:[RACScheduler scheduler]] map:^(User *user)

    { // Download the avatar in a background queue return [[NSImage alloc] initWithContentsOfURL:user.avatarURL]; }] // The assignment will be done on the main thread deliverOn:[RACScheduler mainThreadScheduler]]; Control when and where the work is performed
  14. Links ReactiveCocoa repository & Docs http://github.com/ReactiveCocoa/ReactiveCocoa Principles of Reactive Programming

    http://github.com/ReactiveCocoa/ReactiveCocoa/tree/master/Documentation http://www.coursera.org/course/reactive Tutorials http://www.raywenderlich.com/62699/reactivecocoa-tutorial-pt1 http://www.raywenderlich.com/62796/reactivecocoa-tutorial-pt2 Books Functional Reactive Programming on iOS by Ash Furrow