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

ReactiveCocoa

 ReactiveCocoa

A brief overview of reactive programming and how it is applied to Objective C.

Avatar for AppFoundry

AppFoundry

April 11, 2014
Tweet

More Decks by AppFoundry

Other Decks in Programming

Transcript

  1. REACTIVECOCOA* TOPICS ⇁  BUILDING BLOCKS ⇁  COLLECTION TRANSFORMATION ⇁  ASYNCHRONOUS

    PROGRAMMING ⇁  COMPOSITION & PARALLELIZATION ⇁  DATA BINDING & MVVM
  2. FRP ❝FRP IS A HIGH-LEVEL WAY TO WORK WITH INTERACTIONS.

    IT PROVIDES CONTROL FLOW STRUCTURES FOR TIME. IT IS BUILT AROUND THE IDEA OF TIME-VARYING VALUES, CALLED SIGNALS. ❞ — elm-lang.org
  3. FRP ❝REPRESENT & QUERY ASYNCHRONOUS DATA STREAMS, AND PARAMETERIZE THE

    CONCURRENCY IN THE ASYNCHRONOUS DATA STREAMS USING SCHEDULERS.❞ — rx.codeplex.com
  4. ERIK MEIJER ⇁  FUNCTIONAL PROGRAMMING & COMPILER IMPLEMENTATION ⇁  MICROSOFT

    (2000 – 2013) ⇁ REACTIVE EXTENSIONS (RX) FOR C#/.NET
  5. DB EXAMPLE [[[[db getArticles] filter:^BOOL(Article* article) { return article.isDraft; }]

    map:^Draft*(Article* article) { Draft *draft = [Draft new]; draft.title = article.title; return draft; }] doNext:^(Draft *draft) { // Do something with each draft }];
  6. TOUCH EXAMPLE [[[[view touchSignals] filter:^BOOL(UITouch* touch) { return touch.duration >

    100; }] map:^TouchPoint*(UITouch* touch) { TouchPoint* tp = [TouchPoint new]; tp.x = touch.x; tp.y = touch.y; return tp; }] doNext:^(TouchPoint *tp) { // Do something with each tp }];
  7. STREAM ⇁  ABSTRACT BASE TYPE ⇁  ANY SERIES OF OBJECT

    VALUES ⇁  VALUES AVAILABLE NOW OR IN FUTURE RACStream
  8. SIGNAL ⇁  PUSH-DRIVEN STREAM ⇁  DATA TO BE DELIVERED IN

    THE FUTURE ⇁  VALUES SENT AS THEY ‘ARRIVE’ RACSignal A B
  9. ⇁  SUBSCRIBE TO RECEIVE EVENTS ⇁  SENDS 3 EVENT TYPES

    ⇁ ‘NEXT’ ⇁ ‘ERROR’ ⇁ ‘COMPLETE’ ⇁  IMMUTABLE A B
  10. COLD ⇁  DEFAULT ⇁  START WORK WITH EACH NEW SUBSCRIPTION

    RACSignal HOT ⇁  WORK STARTS ONCE ⇁  FOR ALL SUBSCRIPTIONS RACMultiCastConnection
  11. SIDE-EFFECTS ⇁  WORK THAT HAPPENS AS SIGNALS MOVE THROUGH ⇁ 

    NEXT ⇁  ERROR ⇁  COMPLETE ⇁  UI ⇁  FIRING OTHER SIGNALS ⇁ …
  12. SUBJECT ⇁  INHERITS FROM SIGNAL ⇁  MUTABLE ⇁  ‘NEXT’, ‘ERROR’,

    ‘COMPLETE’ EVENTS FROM OUTSIDE ⇁  BRIDGE NON-REACTIVE CODE RACSubject
  13. SUBSCRIPTION ⇁  WAITS FOR EVENTS FROM A SIGNAL ⇁  DISPOSED

    WHEN SIGNAL COMPLETES/ERRORS id<RACSubscriber>
  14. DISPOSABLE ⇁  CANCELLATION & RESOURCE CLEANUP ⇁  UNSUBSCRIBES FROM SIGNALS

    ⇁  IMPLICIT OR EXPLICIT ⇁  RESULT OF A SUBSCRIPTION RACDisposable
  15. SCHEDULER ⇁ (SERIAL) EXECUTION QUEUE FOR SIGNALS ⇁  SIMILAR TO THREADS

    ⇁  SUPPORTS CANCELLATION ⇁  NO SYNCHRONOUS EXECUTION ⇁  PREVENTS DEADLOCKS RACScheduler
  16. ⇁  CREATES & SUBSCRIBES TO A SIGNAL ⇁  IN RESPONSE

    TO UI ACTION ⇁  TYPICAL USES ⇁  HANDLERS ⇁  VIEWMODELS COMMAND RACCommand
  17. EXAMPLE NSArray *got = @[@”Tyrion”, @”Jaime”, @”Daenerys”, @”Jon”]; NSMutableArray *gotPeople

    = [[NSMutableArray alloc] init]; for(NSString *name in got) { if([name hasPrefix:@”J”]) { continue; } Person *p = [Person new]; p.name = name; [gotPeople addObject:p] }
  18. EXAMPLE NSArray *got = @[@”Tyrion”, @”Jaime”, @”Daenerys”, @”Jon”]; [[got.rac_sequence filter:^BOOL(NSString

    *name) { return [name hasPrefix:@”J”]; }] map:^Person*(NSString *name) { Person *p = [Person new]; p.name = name; return p; }];
  19. MODELS ⇁  EVENT-DRIVEN / CALLBACK-BASED ⇁  INTERRUPTS FLOW ⇁  NESTING

    = PROBLEMATIC ⇁  FUTURES / PROMISES ⇁  ENCAPSULATES SUCCESS / FAILURE HANDLERS ⇁  SOME SEQUENCING & PARALLELISM ⇁  BOTH: REPRESENT SINGLE VALUES
  20. SIGNALS ⇁  LINEAR FLOW (LIMITED NESTING) ⇁  ENCAPSULATES STREAM OF

    VALUES OVER TIME ⇁  INFINITELY COMPOSABLE ⇁  SIMPLIFIED SEQUENCING & PARALLELIZATION ⇁  SERIAL QUEUE
  21. EXAMPLE [[[[[self.service getUpcomingMeetings] collect] doNext:^(NSArray *upcomingMeetings) { self.upcomingMeetings = upcomingMeetings;

    }] doError:^(NSError *error) { [[AlertView alertWithError:error] show]; }] subscribeCompleted:^{ [self.tableView reloadData]; }];
  22. EXAMPLE [[[[[self.service getUpcomingMeetings] collect] doNext:^(NSArray *upcomingMeetings) { self.upcomingMeetings = upcomingMeetings;

    }] doError:^(NSError *error) { [[AlertView alertWithError:error] show]; }] subscribeCompleted:^{ [self.tableView reloadData]; }]; SIGNAL   SUBSCRIPTION   SIDE-­‐EFFECT   SIDE-­‐EFFECT   OPERATION   (return)  DISPOSABLE  
  23. COMPOSITION – EXAMPLE [client logInWithSuccess:^{ [client loadCachedMessagesWithSuccess:^(NSArray *messages) { [client

    fetchMessagesAfterMessage:messages.lastObject success:^(NSArray *nextMessages) { NSLog(@"Fetched all messages."); } failure:^(NSError *error) { [self presentError:error]; }]; } failure:^(NSError *error) { [self presentError:error]; }]; } failure:^(NSError *error) { [self presentError:error]; }];
  24. COMPOSITION – EXAMPLE [[[[client logIn] then:^{ return [client loadCachedMessages]; }]

    flattenMap:^(NSArray *messages) { return [client fetchMessages:messages.lastObject]; }] subscribeError:^(NSError *error) { [self presentError:error]; } completed:^{ NSLog(@"Fetched all messages."); }];
  25. DATA BINDING ⇁  NON-STANDARD ON IOS ⇁  REPLACEMENT FOR KEY-VALUE

    OBSERVING (KVO) ⇁  TURNS REGULAR PROPERTIES INTO SIGNALS