I am using [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
in my app. By using this my app is terminated in iOS 4.3 but it is working fine in iOS 5.0.
How to use this in iOS 4.3 can any one help me.
Here's a full implementation that works for me. Feel free to rename it and add as a category on NSURLConnection
, or just add it as a local method in the class you're working in.
-(void)sendAsynchronousRequest:(NSURLRequest*)request queue:(NSOperationQueue*)queue completionHandler:(void(^)(NSURLResponse *response, NSData *data, NSError *error))handler
{
__block NSURLResponse *response = nil;
__block NSError *error = nil;
__block NSData *data = nil;
// Wrap up synchronous request within a block operation
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
}];
// Set completion block
// EDIT: Set completion block, perform on main thread for safety
blockOperation.completionBlock = ^{
// Perform completion on main queue
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
handler(response, data, error);
}];
};
// (or execute completion block on background thread)
// blockOperation.completionBlock = ^{ handler(response, data, error); };
// Execute operation
[queue addOperation:blockOperation];
}
EDIT
I had to modify the method because I was making UIKit calls in my completion block (e.g. updating labels etc). So it's actually a bit safer to call completion block on the main thread. (original version commented out)
The method you are trying to use is only available on iOS 5. For earlier OSes, consider using
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error
and wrapping it into a new thread to achieve async behavior.
Both H2CO3 and Ken Thomases suggestions are right.
In addition, you could take a look at ios4-implementation-of-nsurlconnection-sendasynchronousrequestqueuecompletio.
If you use the main queue as the queue where the completion handler performs, you could use (as Tom suggested) the delegate pattern. To avoid duplicate code, you could use a wrapper on NSURLConnection
delegates mechanism.
In the other case, if you want to maintain the async behaviour and you don't want to deal with sync call (as H2CO3 suggested, note that his suggestion is also valid) and the completion handler performs in a different queue, then I suggest you to wrap the async delegate pattern in a NSOperation
class. This approach is quite difficult but you can find a good way of do this in Concurrent Operations Demystified (see both the posts).
Hope it helps.