ReactiveCocoa at MobiDevDay 2013

ReactiveCocoa at MobiDevDay 2013

https://github.com/andrewsardone/RACMobiDevDay
Recording: https://vimeo.com/65637501

These are the slides from my MobiDevDay 2013 talk on ReactiveCocoa.

ReactiveCocoa (RAC) is an Objective-C framework for Functional Reactive Programming. It builds off of Cocoa's own key-value observing mechanism to provide a high-level, declarative API for composing operations on streams of data, state, and asynchronous tasks. What does all of that mean? We'll find out as we explore RAC's potential for helping us better reason about the creation of our apps.

Also included in the Declarative Programming section is https://github.com/mneorr/ObjectiveSugar

Additional resources:

https://github.com/ReactiveCocoa
https://pinboard.in/u:andrewsardone/t:ReactiveCocoa
https://github.com/andrewsardone/RACMobiDevDay
http://nsbrief.com/81-justin-spahr-summers/
http://j.mp/joshaberio
http://j.mp/reactiveextensions

F3c52a0537360c85b46e043711cab0c6?s=128

Andrew Sardone

May 04, 2013
Tweet

Transcript

  1. ReactiveCocoa or: How I Learned to Stop Worrying and Learn

    FRP
  2. Abstraction

  3. Objective-C OOP #import <Foundation/Foundation.h> @interface Person : NSObject @property (nonatomic,

    copy) NSString *name; - (void)say:(NSString *)message withExclaim:(BOOL)exclaim; @end @implementation Person - (void)say:(NSString *)message withExclaim:(BOOL)exclaim { if (exclaim) { message = [message uppercaseString]; } NSLog(@"%@", message); } @end
  4. Declarative Programming

  5. NSArray *array = @[@"foo", @"bar", @"baz"]; NSMutableArray *uppercaseArray = [NSMutableArray

    array]; for (int i = 0; i < array.count; i++ ) { uppercaseArray[i] = [array[i] uppercaseString]; } // uppercaseArray: @[ @"FOO", @"BAR", @"BAZ" ] id u = [@[@"foo", @"bar", @"baz"] map:^id(NSString *s) { return [s uppercaseString]; }]; // u: @[ @"FOO", @"BAR", @"BAZ" ] Describes how to compute Describes what to compute
  6. Declarative Programming = Good thing

  7. The State of Our Apps

  8. Lots of state Poor code locality Boilerplate

  9. Complexity

  10. Taps Keyboard events GPS events Web service responses … UI

    updates File on disk New DB record Web service request … INPUT w!r" I#p$% &#' O$%p$% by Josh Abernathy http://j.mp/joshaberio OUTPUT
  11. Is there a better abstraction?

  12. Reactive Programming “Programming around data flows and the propagation of

    change”
  13. a = 2 b = 2 c = a +

    b # c is 4 b = 3 # now what’s the value of c?
  14. None
  15. Data types that represent a value over time

  16. Streams sequences of values over time Signals observable streams affords

    reaction to past, present, and future values
  17. a := 2 # signal b := 2 # signal

    c := a + b # signal binding # other signals b 2 3 c a + b 4 5 2 a 4 7 5 6 1
  18. ReactiveCocoa “A [Cocoa] framework for composing and transforming streams of

    values”
  19. KVO property UI events Network request Async work … Values

    over time https://speakerdeck.com/joshaber/reactivecocoa-for-a-better-world
  20. @interface RACSignal : RACStream [RACAble(self.username) subscribeNext:^(NSString *newName) { NSLog(@"%@", newName);

    }]; https://github.com/ReactiveCocoa/ReactiveCocoa/blob/master/README.md next completed error sending a single value done sending all values & successful sending values but terminated in error
  21. [self.textField.rac_textSignal subscribeNext:^(NSString *text) { NSLog(@"Incoming text signal: %@", text); }];

  22. [[self.textField.rac_textSignal map:^id(id text) { return [text stringByAppendingString:@" – map'd it"];

    }] subscribeNext:^(NSString *text) { NSLog(@"Incoming text signal: %@", text); }];
  23. RACSignal *url = [[[[button rac_signalForControlEvents:UIControlEventTouchUpInside] map:^id(id _) { return NSString

    *s = [@[ [NSURL URLWithString:@"http://nutshell.com"], [NSURL URLWithString:@"http://google.com"], [NSURL URLWithString:@"http://wikipedia.org"], [NSURL URLWithString:@"http://apple.com"], [NSURL URLWithString:@"http://github.com/ReactiveCocoa/ReactiveCocoa"], ] aps_randomObject]; }] publish] autoconnect]; RACSignal *html = [[url flattenMap:^RACStream *(NSURL *url) { NSStringEncoding encoding = NSUTF8StringEncoding; return [NSString rac_readContentsOfURL:url usedEncoding:&encoding scheduler:[RACScheduler scheduler]; }] deliverOn:RACScheduler.mainThreadScheduler]; RAC(label, text) = [url map:^id(NSURL *u) { return u.absoluteString; }]; [webView rac_liftSelector:@selector(loadHTMLString:baseURL:) withObjects:html, url];
  24. field.enabled = NO; [worker doWorkWithCompletionBlock:^(id result, NSError *error) { field.enabled

    = YES; if (error) { /* handle error */ } else /* handle result */ }]; RACCommand *doWork = [worker doWorkAsCommand]; RAC(field, enabled) = [RACAble(doWork, executing) not]; // later, when we want to do the work // our UI pipes are plugged together so we don’t need to // worry about that [doWork execute:sender]; // handle result of doWork somewhere else where it matters … less imperative … more declarative
  25. Demo

  26. None
  27. None
  28. None
  29. None
  30. None
  31. None
  32. None
  33. None
  34. None
  35. None
  36. None
  37. None
  38. None
  39. None
  40. None
  41. None
  42. None
  43. None
  44. None
  45. None
  46. None
  47. None
  48. None
  49. None
  50. None
  51. None
  52. None
  53. None
  54. None
  55. None
  56. None
  57. None
  58. None
  59. None
  60. None
  61. None
  62. None
  63. None
  64. None
  65. None
  66. None
  67. None
  68. None
  69. None
  70. None
  71. None
  72. None
  73. None
  74. None
  75. None
  76. None
  77. None
  78. None
  79. None
  80. None
  81. None
  82. Reduce unnecessary state Better code locality Fluent interface Simple data

    structures Composing functions
  83. Thanks!

  84. Andrew Sardone twitter: @andrewa2 app.net: @andrewsardone github.com/andrewsardone github.com/ReactiveCocoa pinboard.in/u:andrewsardone/t:ReactiveCocoa github.com/andrewsardone/RACMobiDevDay

    nsbrief.com/81-justin-spahr-summers/ Input and Output – j.mp/joshaberio Reactive Extensions (Rx) – j.mp/reactiveextensions