Use RACCommand with Asynchronous Network Operation

1.4k views Asked by At

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?

1

There are 1 answers

0
Ash Furrow On BEST ANSWER

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