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.

103e1ebcacd620770cf32a36b9aba17e?s=128

AppFoundry

April 11, 2014
Tweet

Transcript

  1. None
  2. None
  3. OVERVIEW ⇁  FUNCTIONAL REACTIVE PROGRAMMING ⇁  REACTIVECOCOA* ⇁  RESPONDER /

    CALLHANDLE? ⇁  CODE EXAMPLES
  4. REACTIVECOCOA* TOPICS ⇁  BUILDING BLOCKS ⇁  COLLECTION TRANSFORMATION ⇁  ASYNCHRONOUS

    PROGRAMMING ⇁  COMPOSITION & PARALLELIZATION ⇁  DATA BINDING & MVVM
  5. FUNCTIONAL REACTIVE PROGRAMMING First look at

  6. 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
  7. ٩۹(๏̯͡๏)ゞ? WAIT. WHAT?!

  8. FRP ❝REPRESENT & QUERY ASYNCHRONOUS DATA STREAMS, AND PARAMETERIZE THE

    CONCURRENCY IN THE ASYNCHRONOUS DATA STREAMS USING SCHEDULERS.❞ — rx.codeplex.com
  9. FUNCTIONAL REACTIVE INPUT ⤑ OUTPUT AVOID STATE AVOID MUTABLE DATA

    NO SIDE-EFFECTS DECLARATIVE
  10. FUNCTIONAL REACTIVE DATA FLOW CHANGE PROPAGATION SIDE-EFFECTS EVENTS NON-BLOCKING COMPOSITION

  11. (-_-)ゞ

  12. None
  13. None
  14. DIFFERENT PARADIGM NOT JUST A LIBRARY

  15. PROCEDURAL (HOW?)

  16. RISE OF FRP

  17. ERIK MEIJER ⇁  FUNCTIONAL PROGRAMMING & COMPILER IMPLEMENTATION ⇁  MICROSOFT

    (2000 – 2013) ⇁ REACTIVE EXTENSIONS (RX) FOR C#/.NET
  18. WHAT’S THE DIFFERENCE BETWEEN

  19. NOTHING.

  20. BOTH ARE JUST

  21. 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 }];
  22. 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 }];
  23. RX.NET REACTIVECOCOA RXJAVA* RXJS RXCPP RXPY RXRB BACONJS

  24. FRP IN DESIGN PATTERNS 3-in-1

  25. IENUMERATOR<T> ⇁  ENUMERABLE<T> bool MoveNext()

  26. IOBSERVER<T> void OnCompleted() void OnError() void OnNext() OBSERVABLE<T> Disposable subscribe(Observer<T>)

  27. DISPOSABLE void dispose()

  28. SIGNAL IENUMERATOR<T> IOBSERVER<T> ENUMERABLE<T> DISPOSABLE OBSERVABLE<T>

  29. REACTIVECOCOA Building Blocks

  30. STREAM ⇁  ABSTRACT BASE TYPE ⇁  ANY SERIES OF OBJECT

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

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

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

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

    NEXT ⇁  ERROR ⇁  COMPLETE ⇁  UI ⇁  FIRING OTHER SIGNALS ⇁ …
  35. SEQUENCE ⇁  PULL-DRIVEN STREAM ⇁  DATA ALREADY AVAILABLE ⇁  VALUES

    REQUESTED LAZILY RACSequence
  36. SUBJECT ⇁  INHERITS FROM SIGNAL ⇁  MUTABLE ⇁  ‘NEXT’, ‘ERROR’,

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

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

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

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

    TO UI ACTION ⇁  TYPICAL USES ⇁  HANDLERS ⇁  VIEWMODELS COMMAND RACCommand
  41. BUTTON TAP SVC CALL FILTER MAP ARRAY à UI FLATTENMAP

    FILTER
  42. SIGNAL OPERATIONS ⇁ -CONCAT: ⇁ -MERGE: ⇁ -FLATTENMAP: ⇁ -THEN:

  43. SIGNAL OPERATIONS ⇁ -RETRY: ⇁ -IF:THEN:ELSE ⇁ -DELAY: ⇁ -THROTTLE: ⇁ -TAKE: ⇁ -TRY:CATCH: ⇁ +RETURN: operators

     
  44. COLLECTION TRANSFORMATION

  45. COLLECTION TRANSFORMATION ⇁  HIGHER ORDER FUNCTIONS ⇁  MAP ⇁  FILTER

    ⇁  FOLD ⇁  REDUCE
  46. 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] }
  47. 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; }];
  48. ASYNCHRONOUS PROGRAMMING

  49. MODELS ⇁  EVENT-DRIVEN / CALLBACK-BASED ⇁  INTERRUPTS FLOW ⇁  NESTING

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

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

    }] doError:^(NSError *error) { [[AlertView alertWithError:error] show]; }] subscribeCompleted:^{ [self.tableView reloadData]; }];
  52. 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  
  53. COMPOSITION & PARALLELIZATION

  54. COMPOSITION ⇁  DEPENDENT TASKS ⇁  E.G. NETWORK REQUESTS ⇁  SIGNAL

    CHAINING ⇁  NESTING
  55. 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]; }];
  56. 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."); }];
  57. PARALLELIZATION ⇁  ONE-BY-ONE ⇁ [RACSignal -concat:@[signals ]] ⇁  IN PARALLEL ⇁ [RACSignal

    -combineLatest:@[signals ]] ⇁  RETURN TYPES? JUST SIGNALS.
  58. DATA BINDING & MVVM ReactiveCocoa

  59. DATA BINDING ⇁  NON-STANDARD ON IOS ⇁  REPLACEMENT FOR KEY-VALUE

    OBSERVING (KVO) ⇁  TURNS REGULAR PROPERTIES INTO SIGNALS
  60. DATA BINDING [[RACObserve(self, username) filter:^(NSString *newName) { return [newName hasPrefix:@"j"];

    }] subscribeNext:^(NSString *newName) { NSLog(@"%@", newName); }];
  61. MVVM VIEW VIEWMODEL MODEL NOTIFIES   COMMANDS   REFERENCES  

  62. RESPONDER / CALLHANDLE ?

  63. CODE EXAMPLES