0
votes

trying to send the following message

- (NSArray *)callSwaggerwithStart:(NSNumber *)start andCount:(NSNumber *)count
{
    [api messageWithCompletionBlock:start count:count filter:@"image" completionHandler:^(CustomResponse *output, NSError *error) {
        if (!error) {
            return [NSArray arrayWithArray:[[output toDictionary] valueForKey:@"items"]];
        } else {
            NSLog(@"ERROR IN CallApi, %@", &error);
        }
    }];
    return nil;
}

I get the following errors:

Incompatible block pointer types

Control may reach end of non-void block

The block is from an Api class, and I would like to create a method since it is used multiple times in one controller. What is keeping the code from being able to return the nested NSArray value?

3
Why does the callSwaggerwithStart... method have a return value? It's pointless when dealing with a asynchronous block that won't return data until long after the method returns. You need to rethink how this works. - rmaddy
I had added the return value, will be removing it then. Thanks! - aug2uag

3 Answers

1
votes

The API completion block is executed asynchronously, so you cannot synchronously return anything it computes to the caller of callSwaggerWithStart.... The completionHandler is likely to be executed much later than the method returns.

A valid approach would be to also make callSwaggerWithStart... asynchronous, as follows:

- (void)callSwaggerwithStart:(NSNumber *)start andCount:(NSNumber *)count completionHandler:(void (^)(NSArray *result, NSError *error))completionHandler
{
    [api messageWithCompletionBlock:start count:count filter:@"image" completionHandler:^(CustomResponse *output, NSError *error) {
        if (completionHandler) {
            if (!error) {
                completionHandler([output toDictionary][@"items"]], error);
            } else {
                completionHandler(nil, error);
            }
        }
    }];
}
1
votes

The -messageWithCompletionBlock:etc: method appears to be asynchronous, which means that, as it’s currently written, the block will get called after -callSwaggerEtc: returns. The “return” inside the block returns from the block, not from the method itself You have two options—change -callSwaggerEtc: to take a completion handler of its own, or use a semaphore to make it synchronous and wait to return until the block gets called.

0
votes

start is an NSNumber, not a block. Or messageWithCompletionBlock: is really badly named...

completionHandler does not expect a return. It's also a block, so returning from there just exits the block, not the containing method.

Your method expects to return an array, you expect to be able to do that from within a block - you are mistaken. You need to change your design so the method doesn't return an array (maybe it calls a block that it is passed as a parameter) or it gets the array in a different way.