Richard Marr
Richard Marr

Reputation: 3064

NSURLConnection sendSynchronousRequest seems to hang

This HTTP call seems to be hanging and I can't see why. The logging line after the call never runs.

I'm almost certainly doing something extremely stupid, but if anyone can spot what it is I'd be grateful. As far as I can see my code is equivalent to the docs.

It doesn't seem to matter what URL I use, and the HTTP request is never logged by the server (if pointed at one).

NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com/"]];

NSURLResponse *res = nil;
NSError *err = nil;

NSLog(@"About to send req %@",req.URL);

NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:&res error:&err];

NSLog(@"this never runs");

Any ideas?

Update

Thanks to everyone who's posted so far. Still seeing the problem. A bit more detail:

Upvotes: 10

Views: 14704

Answers (5)

Nikos M.
Nikos M.

Reputation: 13783

Run the request in a background queue so it does not block the main thread where UI updates occur:

 dispatch_queue_t myQueue = dispatch_queue_create("myQueue", NULL);

    // execute a task on that queue asynchronously
    dispatch_async(myQueue, ^{
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com/"]];

NSURLResponse *res = nil;
NSError *err = nil;

NSLog(@"About to send req %@",req.URL);

NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:&res error:&err];

    });

Upvotes: 7

Richard Marr
Richard Marr

Reputation: 3064

This code works in other contexts so it's clear that it's happening because the call is being made from the cachedResponseForRequest method of an NSURLCache. Running it elsewhere works fine.

Since this was intended to enable a proxy between AJAX calls in an embedded UIWebView and the server (for the purpose of not having to rewrite API request signing code in JS) I've worked around it using Marcus Westin's WebViewProxy class which works a treat.

Upvotes: 2

Sam Fischer
Sam Fischer

Reputation: 1472

Its a synchronous method - i.e. it runs on the main thread. Therefore, your application will hang - and it'll wait till the data is downloaded.

To prevent it: use the sendAsynchronousRequest method. It'll run this process on a background thread and won't disrupt your application or simply - won't make it hang.

Here's how to use sendAsynchronousRequest:

NSURL *url = [NSURL URLWithString:@"YOUR_URL_HERE"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
    //the NSData in the completion handler is where your data is downloaded.
}];

Considering all the circumstances, I think that the problem exists due to your delegate declaration. So declare <NSURLConnectionDataDelegate> and the declare an NSMutableData : myData object and an NSURLConnection : urlConnection as properties. Now use this :

NSURL *url = [NSURL URLwithString : @"YOUR_URL_HERE"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
*urlConnection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];


-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [myData setLength:0]; 
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{

    [myData appendData:data];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    //You can use the complete downloaded data - NSMutableData here.
}

Upvotes: -2

TamilKing
TamilKing

Reputation: 1643

Add delegate <NSURLConnectionDataDelegate>

NSURL *url = [[NSURL alloc]initWithString:[NSString stringWithFormat:@"Your string here"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
    [connection start];//It will start delegates


-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [received_data setLength:0];//Set your data to 0 to clear your buffer 
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{

    [received_data appendData:data];//Append the download data..
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    //Use your downloaded data here
}

This method more better to download data.. It wont use main thread so the app wont hang.. I hope it will be more useful for you

Upvotes: 3

user1988
user1988

Reputation: 811

When your request succeeds with the response then your NSLog will execute because sendSynchronousRequest method works on main thread.

Upvotes: -1

Related Questions