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

ReactiveCocoa at mdevcon 2014

Ash Furrow
March 08, 2014

ReactiveCocoa at mdevcon 2014

Ash Furrow

March 08, 2014

More Decks by Ash Furrow

Other Decks in Technology


  1. ReactiveCocoa Ash Furrow

  2. — Shunryu Suzuki “In the beginner’s mind there are many

    possibilities, in the expert's mind there are few.”
  3. Agenda • Imperative programming is antiquated and dangerous • Functional

    reactive programming mitigates those dangers • ReactiveCocoa makes FRP easy
  4. BNE ADD1 BRA NONE1 ADD1 INY ;increment our counter of

    1's NONE1 LDAA TEMP ;reload accumulator A LSL MASK ;Shift the mask's 1 bit left BNE LOOP1 ;If we haven't finished our loop, branch LDAA #$01 ;load new mask into A STAA MASK ;store the reset mask into MASK TSX ;pull of return address and store in X PULA ;pull off A STAA TEMP ;store the value into temp TXS ;push return address back onto the stack LOOP2 LDAA TEMP ;Load A into TEMP ANDA MASK ;logical AND MASK with A BNE ADD2 ;add one if we need to BRA NONE2 ADD2 INY ;increment our counter of 1's NONE2 LDAA TEMP LSL MASK ;shift our mask left by one BNE LOOP2 ;loop back until we've exhausted positions
  5. Functional Reactive Programming

  6. • Functional • Typically, functions have no side-effects • Programs

    are written as a series of data transformations
  7. Demo https://github.com/AshFurrow/FunctionalDemo

  8. • Reactive • When one thing changes, it effects changes

    in other things • Like a spreadsheet
  9. Functional programming has limits. ! Reactive programming is limited by

    itself. ! FRP is peanut butter and chocolate of programming paradigms.
  10. Functional Reactive Programming • In functional programming, things get hard

    because functions can’t have side-effects • (Every time a function is called, it must return the same result for the same parameters) • In functional reactive programming, time is an implicit parameter • This makes things easy to manage, without using monads
  11. Signals • At the core of FRP are signals •

    Signals send values over time, until they complete or error out • A signal never sends anything after completing or erring • A signal either completes, or errors out, but never both • A signal has no concept of a “current value” or “past values” • It’s like a pipe
  12. Signals • Signals can be chained to transform the values

    that the send • This is core to FRP: data transformation of values sent over time • In math terms, it’s f(g(y))
  13. • ReactiveCocoa is a framework developed by GitHub • ReactiveCocoa

    is an implementation of FRP on iOS/OS X • It’s currently being revamped to version 3.0
  14. Signals • Signals are built on KVO • Creating a

    signal is easy • RACObserve macro • Wraps a @property • Sends a new value for updated property values
  15. RACSignal *signal = RACObserve(object, number); [signal subscribeNext:^id(NSNumber *value) { NSLog(@”%@”,

    value); }];
  16. Signals • Signals always send id, never primitives • Will

    wrap primitives in NSNumber for you
  17. Map • Mapping performs a value transformation on the given

    signal • It “maps” each value sent along the signal to a new value • It then passes that new value along, creating a new signal • This is the canonical value transformation
  18. RACObserve map: subscribeNext:

  19. RACSignal *signal = RACObserve(object, number); [[signal map:^id(NSNumber *value) { return

    [value stringValue]; }] subscribeNext:^id(NSString *string) { NSLog(@”%@”, string); }];
  20. Combine Latest • Combines two or more signals’ values into

    one • Useful for waiting for conditions to be met • Useful for deciding between values
  21. RACObserve combineLatest: reduce: RACObserve

  22. [RACSignal combineLatest:@[someNumberSignal, someStringSignal] reduce:^id(NSNumber *number, NSString *string){ return [NSString stringWithFormat:@"%@:%@",

    number.stringValue, string]; }];
  23. Filter • Filtering allows values that pass some test to

    “pass through”
  24. RACObserve filter: subscribeNext:

  25. [[someNumberSignal filter:^BOOL(NSNumber *value){ return value.integerValue > 5; }] map:^id(NSNumber *value)

    { return [value stringValue]; }];
  26. Bindings • Bindings can bind a property to the latest

    value sent on a signal • Bindings are typically created with the RAC macro • All bindings created with the RAC macro are one-way • Bindings are the secret sauce that hold apps together
  27. RAC(self.textField, text) = RACObserve(self, someString);

  28. NSArray *signalArray = @[self.firstNameField.rac_textSignal, self.lastNameField.rac_textSignal]; ! RAC(self.button, enabled) = [RACSignal

    combineLatest:signalArray reduce:^(NSString *firstName, NSString *lastName){ return @(firstName.length > 0 && lastName.length > 0); }];
  29. Derived State • State is avoided in ReactiveCocoa, but is

    unavoidable in Cocoa • Instead of hacky workarounds, we derive the state from signals • Similar to the last example’s enabled state binding
  30. Other Operators • takeUntil: • scheduleOn: • throttle: • not,

    and, or
  31. Commands • A command represents a unit of work •

    Typically, work that’s done in response to user action • Commands are … confusing • They’ve been replaced in ReactiveCocoa 3.0 by Actions
  32. Two-Way Bindings • Two-way bindings exist, but their use is

    more rare under MVC • They’re more frequently used with MVVM • Created with RACChannelTo macro
  33. Demo https://github.com/AshFurrow/FunctionalReactiveDemo

  34. Demo • Notice subscribeNext: is used for side-effects • Cocoa

    Touch isn’t built on FRP, so we need side-effects • RACObserve captures self in its scope implicitly • Avoid reference cycles! • Network results are delivered on a background scheduler • Use deliverOn: to reschedule them
  35. Model-View-ViewModel

  36. View View Controller Model View Model owns owns Updates Updates

  37. Getting Started • Getting started with ReactiveCocoa is easy •

    Install ReactiveCocoa in your project (CocoaPods or submodule) • Start by replacing KVO methods with RACObserve • Use subscribeNext: for side-effects
  38. http://leanpub.com/iosfrp

  39. @ashfurrow http://ashfurrow.com