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

What the FRP? – Using Reactive Cocoa

What the FRP? – Using Reactive Cocoa

A talk I gave on using Reactive Cocoa in the Rackspace Cloud Control application at NSMeetup July.

Jay Baird

July 23, 2013
Tweet

Other Decks in Programming

Transcript

  1. <RACSubscriber> • Protocol any object can adopt to receive values

    from a signal. • Use RACSignal’s - subscribeNext:error:completed: convenience methods
  2. RACSignal • Push driven stream • As work is completed

    values are sent on the signal to its subscribers • Sends next, error and completed events • Can sends any number of next events, followed by one error or completed (but not both)
  3. RAC(self.image) = [[[client getImage:self.imageId] catch:^RACSignal *(NSError *error) { return [RACSignal

    empty]; // swallow the error }] map:^(NSDictionary *imageDict) { return [Image fromJSON:imageDict[@"image"]]; }];
  4. RACSubject • Think of it as RACMutableSignal • provides sendNext:,

    sendError: and sendCompleted methods • Crazy useful for bridging other code, e.g. AFNetworking
  5. RACSubject *pollTimer = [RACSubject subject]; [[[RACSignal interval:60.0f] takeUntil:[pollTimer doNext:^(id x)

    { NSLog(@"Server poll cancelled"); }]] subscribeNext:^(id x) { NSLog(@"Tick."); } error:^(NSError *error) { NSLog(@"Handle the error condition"); } completed:^{ NSLog(@"Timer completed"); }]; // Cancels the timer. // A unit represents an empty value [pollTimer sendNext:[RACUnit defaultUnit]];
  6. RACSubject *subject = [RACSubject subject]; // +flavors returns a RACSignal

    with flavors // +images returns a RACSignal with images [[RACSignal combineLatest:@[[Flavor flavors], [Image images]]] subscribeError:^(NSError *error) { [subject sendError:error]; } completed:^{ [[client getServers] subscribeNext:^(NSArray *serverJSON) { // Process server JSON [subject sendCompleted]; } error:^(NSError *error) { [subject sendError:error]; } completed:^{ [subject sendCompleted]; }]; }]; return subject;
  7. RACMulticastConnection • Signals start their work on each new subscription

    – great for isolating work • but bad if you have heavy side effects • Made using -multicast: on RACSignal • Creates one and only one subscription
  8. RACSignal *deferredToken = [RACSignal defer:^{ return [self authWithUsername:username key:password]; }];

    _tokenConnection = [deferredToken multicast:[RACReplaySubject subject]]; - (RACSignal *)withAuthToken { [_tokenConnection connect]; return _tokenConnection.signal; } - (RACSignal *)getServers { return [[self withAuthToken] flattenMap:^RACSignal *(NSString *token) { return [self enqueueRequestWithMethod:@"GET" endpoints:self.computeEndpoints path:@"/servers/detail" parameters:nil]; }]; }
  9. KVO