$30 off During Our Annual Pro Sale. View Details »

ReactiveCocoa at mdevcon 2014

Ash Furrow
March 08, 2014

ReactiveCocoa at mdevcon 2014

Ash Furrow

March 08, 2014
Tweet

More Decks by Ash Furrow

Other Decks in Technology

Transcript

  1. ReactiveCocoa
    Ash Furrow

    View Slide

  2. — Shunryu Suzuki
    “In the beginner’s mind there are many possibilities,
    in the expert's mind there are few.”

    View Slide

  3. Agenda
    • Imperative programming is antiquated and dangerous
    • Functional reactive programming mitigates those dangers
    • ReactiveCocoa makes FRP easy

    View Slide

  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

    View Slide

  5. Functional Reactive
    Programming

    View Slide

  6. • Functional
    • Typically, functions have no side-effects
    • Programs are written as a series of data transformations

    View Slide

  7. Demo
    https://github.com/AshFurrow/FunctionalDemo

    View Slide

  8. • Reactive
    • When one thing changes, it effects changes in other things
    • Like a spreadsheet

    View Slide

  9. Functional programming has limits.
    !
    Reactive programming is limited by itself.
    !
    FRP is peanut butter and chocolate of programming paradigms.

    View Slide

  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

    View Slide

  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

    View Slide

  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))

    View Slide

  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

    View Slide

  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

    View Slide

  15. RACSignal *signal = RACObserve(object, number);
    [signal subscribeNext:^id(NSNumber *value) {
    NSLog(@”%@”, value);
    }];

    View Slide

  16. Signals
    • Signals always send id, never primitives
    • Will wrap primitives in NSNumber for you

    View Slide

  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

    View Slide

  18. RACObserve
    map:
    subscribeNext:

    View Slide

  19. RACSignal *signal = RACObserve(object, number);
    [[signal map:^id(NSNumber *value) {
    return [value stringValue];
    }] subscribeNext:^id(NSString *string) {
    NSLog(@”%@”, string);
    }];

    View Slide

  20. Combine Latest
    • Combines two or more signals’ values into one
    • Useful for waiting for conditions to be met
    • Useful for deciding between values

    View Slide

  21. RACObserve
    combineLatest:
    reduce:
    RACObserve

    View Slide

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

    View Slide

  23. Filter
    • Filtering allows values that pass some test to “pass through”

    View Slide

  24. RACObserve
    filter:
    subscribeNext:

    View Slide

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

    View Slide

  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

    View Slide

  27. RAC(self.textField, text) = RACObserve(self, someString);

    View Slide

  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);
    }];

    View Slide

  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

    View Slide

  30. Other Operators
    • takeUntil:
    • scheduleOn:
    • throttle:
    • not, and, or

    View Slide

  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

    View Slide

  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

    View Slide

  33. Demo
    https://github.com/AshFurrow/FunctionalReactiveDemo

    View Slide

  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

    View Slide

  35. Model-View-ViewModel

    View Slide

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

    View Slide

  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

    View Slide

  38. http://leanpub.com/iosfrp

    View Slide

  39. @ashfurrow
    http://ashfurrow.com

    View Slide