Return value for function inside a block

BlackM picture BlackM · Jul 14, 2013 · Viewed 15.2k times · Source

I am using AFNetworking to get data from a server:

-(NSArray)some function {
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
        success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
            NSArray *jsonArray =[JSON valueForKey:@"posts"];
        }
        failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {}
}

So what I am trying to do here is to return the jsonArray to the function. Obviously return is not working.

Answer

jscs picture jscs · Jul 14, 2013

You can't use the completion Block to create a return value for your method. The AFJSONRequestOperation does its work asynchronously. someFunction is going to return while the operation is still working. The success and failure Blocks are how you get resulting values where they need to go.

One option here is to pass in the caller as an argument to your wrapper method so that the completion Block can hand the array off.

- (void)goFetch:(id)caller
{
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
    success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {

        [caller takeThisArrayAndShoveIt:[JSON valueForKey:@"posts"]];
    }
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {}
}

You could also make your caller create and pass a Block to be run on success. Then goFetch: no longer needs to know what properties exist on the caller.

- (void)goFetch:(void(^)(NSArray *))completion
{
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
    success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        if( completion ) completion([JSON valueForKey:@"posts"]);
    }
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {}
}