3

I'm exploring ReactiveCocoa and trying to see whats possible. The issues i'm having is chaining a few network requests together.

I have 2 calls, the first gets a list of identifiers, then for each identifier I make a call to get data corresponding to that id and create a model object and return an array of the objects.

I'm using RACExtensions for AFNetworking to make the requests. Code looks something like this:

- (RACSignal *) identifersInfo
{
    return [[[[self identifiersSignal] flattenMap:^RACStream *(RACTuple *tuple) {
        RACTupleUnpack(AFHTTPRequestOperation *operation, id responseObject) = tuple;
        NSArray *identifiers = responseObject[@"Identifiers"];
        NSArray *requests = [self httpRequestsWithIdentifiers: identifiers];
        return [self.client rac_enqueueBatchOfHTTPRequestOperationsWithRequests: requests];
    }] collect] map:^id(RACTuple *tuple) {
        RACTupleUnpack(AFHTTPRequestOperation *operation, id responseObject) = tuple;
        Model *model = [[Model alloc] init];
        model.title = responseObject[@"Title"];
        model.description = responseObject[@"Description"];
        model.lastUpdated = responseObject[@"LastUpdated"];
        return model;
    }];
}

identifiersSignal method looks like this:

- (RACSignal *) identifiersSignal
{
    return [self.client rac_getPath: @"identifiers" parameters: nil];
}

This returns json dictionary which looks like:

{
  "Identifiers": [
    3,
    4,
    21
  ]
}

I'm actually mocking these calls at the moment and I know they work independently, I'm just trying to piece them together using ReacticeCocoa.

I can't figure out or find any decent samples on how this could be achieved using ReactiveCocoa, although I'm pretty confident it could be.

pablasso
  • 2,479
  • 2
  • 26
  • 32
JFoulkes
  • 2,429
  • 1
  • 21
  • 24
  • 1
    Check out the question "[Chaining dependent signals in ReactiveCocoa](http://stackoverflow.com/questions/15797081/chaining-dependent-signals-in-reactivecocoa/15827396)" and the similar [section in the README](https://github.com/ReactiveCocoa/ReactiveCocoa#chaining-dependent-operations). There's also a wealth of information in the [Documentation](https://github.com/ReactiveCocoa/ReactiveCocoa/tree/master/Documentation) folder, like an explanation of the [basic operators](https://github.com/ReactiveCocoa/ReactiveCocoa/blob/master/Documentation/BasicOperators.md). – Justin Spahr-Summers Jun 08 '13 at 18:37

1 Answers1

0

I had to look into the implementation of the AFNetworking extensions but I think you are misusing a some return values. I haven't tested but it seems like your code should look like this:

- (RACSignal *) identifersInfo {
    return [[[self identifiersSignal] map:^RACSignal *(RACTuple *tuple) {
        RACTupleUnpack(AFHTTPRequestOperation *operation, id responseObject) = tuple;
        NSArray *identifiers = responseObject[@"Identifiers"];
        NSArray *requests = [self httpRequestsWithIdentifiers: identifiers];
        return [self.client rac_enqueueBatchOfHTTPRequestOperationsWithRequests: requests];
    }] map:^Model*(id *reponseObject) {
        Model *model = [[Model alloc] init];
        // same as above
        return model;
    }];
}

It is a little misleading that rac_getPath returns a RACTuple as rac_enqueueBatchOfHTTPRequestOperationsWithRequests returns only a RACStream of the return objects. AFURLConnectionOperation+RACSupport.m The documentation in the header files should be improved with type information to get this straightened out.

Nice code, though.

allprog
  • 16,540
  • 9
  • 56
  • 97