Share
Embed
ReactiveCocoa at mdevcon 2014
Ash Furrow
March 08, 2014
Transcript
39 slides
-
— Shunryu Suzuki “In the beginner’s mind there are many
possibilities, in the expert's mind there are few.” -
Agenda • Imperative programming is antiquated and dangerous • Functional
reactive programming mitigates those dangers • ReactiveCocoa makes FRP easy -
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 -
• Functional • Typically, functions have no side-effects • Programs
are written as a series of data transformations -
• Reactive • When one thing changes, it effects changes
in other things • Like a spreadsheet -
Functional programming has limits. ! Reactive programming is limited by
itself. ! FRP is peanut butter and chocolate of programming paradigms. -
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 -
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 -
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)) -
• 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 -
Signals • Signals are built on KVO • Creating a
signal is easy • RACObserve macro • Wraps a @property • Sends a new value for updated property values -
Signals • Signals always send id, never primitives • Will
wrap primitives in NSNumber for you -
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 -
RACSignal *signal = RACObserve(object, number); [[signal map:^id(NSNumber *value) { return
[value stringValue]; }] subscribeNext:^id(NSString *string) { NSLog(@”%@”, string); }]; -
Combine Latest • Combines two or more signals’ values into
one • Useful for waiting for conditions to be met • Useful for deciding between values -
Filter • Filtering allows values that pass some test to
“pass through” -
[[someNumberSignal filter:^BOOL(NSNumber *value){ return value.integerValue > 5; }] map:^id(NSNumber *value)
{ return [value stringValue]; }]; -
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 -
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); }]; -
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 -
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 -
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 -
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 -
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