iOS dispatch_async and NSURLConnection delegate functions not being called

Pete picture Pete · Jan 20, 2012 · Viewed 12.5k times · Source

I've edited this post to make it simpler to read, I think.

I need to call an NSUrlConnection after I've finished doing some intensive string manipulation in a dispatch_async block.

The URL I call has got .htaccess authentication on it, so I can't use a synchronous connection.

But the NSURLConnection delegate methods are not being called. I know the URL loads after about 5 seconds in the browser, and I've tested the code with a simple URL with no authentication and it makes no difference.

What is stopping the delegate methods being called?

This function does some string manipulation stuff, and takes a while to finish:

- (void)performSearch {

    // set some defaults and work out if it is a valid search, setting bSearchOk

    if (bSearchOk) {

        // update some interface elements
        self.msgBox.text = @"Translating...";            
        self.plateInput.enabled = NO;
        self.searchProgress.hidden = NO;

        dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

            // create a new search
            Search *oPlateSearch = [[Search alloc] initWithTerm:thisTerm];

            // ...
            // perform search... this calls a variety of slow and intensive functions
            // ...

            self.aFinalPlates = [oPlateSearch.aValidated copy];
            self.aCurrentPlates = [oPlateSearch.aFinals copy];        

            dispatch_async( dispatch_get_main_queue(), ^{                 
                [oPlateSearch release];              

                // make ajax call to check if plates can be bought
                [self getPrices];                 
            });
        });

    } else {
        // hide results
        self.searchResults.hidden = YES;
    }

}

And this is the one called towards the end of the block above

/* call to get plate availability and prices */
-(void) getPrices {
    // set return message
    self.msgBox.text = @"Getting prices and availability";

    // ...
    // then I build my strRequest var, which is a valid working URL
    // ...

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:strRequest]];

    NSURLConnection *loginConnection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];

    NSLog('This will get logged');

    if(loginConnection) {
        NSLog('This will also get logged');
        self.jsonSearchResponse = [[[NSMutableData data] retain] autorelease];
        NSLog('And this will get logged, so it's not throwing errors');
    } else {
        NSLog(@"Failed to get search results");
    }
}

Update: I've tried this as well, as it was an accepted in answer on another similar question, but it hasn't worked:

NSURLConnection *loginConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[loginConnection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
[loginConnection start];

Based on this question: Why NSURLConnection delegate methods don't get called, when using the global dispatch queue?

Answer

Pete picture Pete · Jan 27, 2012

Someone from iphonedevsdk.com forum answered this for me:

http://www.iphonedevsdk.com/forum/iphone-sdk-development/97415-dispatch_async-nsurlconnection.html

The answer was to use:

 [self performSelectorOnMainThread:@selector(getPrices) withObject:Nil waitUntilDone:NO];