Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use RACCommand with Asynchronous Network Operation

I'm using UAGitHubEngine to access GitHub's API. I want to write a functional reactive app to fetch some data. I'm relying on on the code here to set up an asynchronous network request. What I'm looking for is the team id of some team named "General". I can do the filtering/printing part OK:

[[self.gitHubSignal filter:^BOOL(NSDictionary *team) {
    NSString *teamName = [team valueForKey:@"name"];
    return [teamName isEqualToString:@"General"];
}] subscribeNext:^(NSDictionary *team) {

    NSInteger teamID = [[team valueForKey:@"id"] intValue];

    NSLog(@"Team ID: %lu", teamID);
}];

But setting up the command is a mystery to me:

self.gitHubCommand = [RACCommand command];

self.gitHubSignal = [self.gitHubCommand addSignalBlock:^RACSignal *(id value) {
    RACSignal *signal = ???

    return signal;
}];

How do I set up the signal block to return a signal that pushes an event when some asynchronous network call returns?

like image 492
Ash Furrow Avatar asked Apr 02 '13 17:04

Ash Furrow


1 Answers

The answer was in RACReplaySubject, which AFNetworking uses to wrap its asynchronous requests.

self.gitHubCommand = [RACCommand command];

self.gitHubSignals = [self.gitHubCommand addSignalBlock:^RACSignal *(id value) {
    RACReplaySubject *subject = [RACReplaySubject subject];

    [engine teamsInOrganization:kOrganizationName withSuccess:^(id result) {

        for (NSDictionary *team in result)
        {
            [subject sendNext:team];
        }

        [subject sendCompleted];            
    } failure:^(NSError *error) {
        [subject sendError:error];
    }];

    return subject;
}];

Since addSignalBlock: returns a signal of signals, we need to subscribe to the next signal it emits.

[self.gitHubSignals subscribeNext:^(id signal) {
    [signal subscribeNext:^(NSDictionary *team) {
        NSInteger teamID = [[team valueForKey:@"id"] intValue];

        NSLog(@"Team ID: %lu", teamID);
    }];
}];

Finally, the addSignalBlock: block isn't executed until the command is executed, which I managed with the following:

[self.gitHubCommand execute:[NSNull null]];
like image 141
Ash Furrow Avatar answered Sep 27 '22 19:09

Ash Furrow