From feaf0814c4cee18b41b252c29daca537ffa6dc72 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 6 Feb 2012 13:29:00 -0800 Subject: [PATCH 1/4] add support for setting custom success/failure callback queues. Defaults to main queue if nothing set. --- AFNetworking/AFHTTPRequestOperation.h | 13 +++++++ AFNetworking/AFHTTPRequestOperation.m | 37 ++++++++++++++++++- AFNetworking/AFImageRequestOperation.m | 4 +- AFNetworking/AFJSONRequestOperation.m | 22 ++++++----- AFNetworking/AFPropertyListRequestOperation.m | 4 +- AFNetworking/AFXMLRequestOperation.m | 6 ++- 6 files changed, 68 insertions(+), 18 deletions(-) diff --git a/AFNetworking/AFHTTPRequestOperation.h b/AFNetworking/AFHTTPRequestOperation.h index 350b64a..235cc1a 100644 --- a/AFNetworking/AFHTTPRequestOperation.h +++ b/AFNetworking/AFHTTPRequestOperation.h @@ -31,6 +31,8 @@ NSIndexSet *_acceptableStatusCodes; NSSet *_acceptableContentTypes; NSError *_HTTPError; + dispatch_queue_t _successCallbackQueue; + dispatch_queue_t _failureCallbackQueue; } ///---------------------------------------------- @@ -71,6 +73,17 @@ */ @property (readonly) BOOL hasAcceptableContentType; +/** + The callback dispatch queue on success. If this is NULL (default), the main queue is used. + */ +@property (nonatomic) dispatch_queue_t successCallbackQueue; + +/** + The callback dispatch queue on failure. If this is NULL (default), the main queue is used. + */ +@property (nonatomic) dispatch_queue_t failureCallbackQueue; + + /** A Boolean value determining whether or not the class can process the specified request. For example, `AFJSONRequestOperation` may check to make sure the content type was `application/json` or the URL path extension was `.json`. diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 38802c1..2fa2326 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -30,6 +30,9 @@ @synthesize acceptableStatusCodes = _acceptableStatusCodes; @synthesize acceptableContentTypes = _acceptableContentTypes; @synthesize HTTPError = _HTTPError; +@synthesize successCallbackQueue = _successCallbackQueue; +@synthesize failureCallbackQueue = _failureCallbackQueue; + - (id)initWithRequest:(NSURLRequest *)request { self = [super initWithRequest:request]; @@ -46,6 +49,8 @@ [_acceptableStatusCodes release]; [_acceptableContentTypes release]; [_HTTPError release]; + if (_successCallbackQueue) { dispatch_release(_successCallbackQueue), _successCallbackQueue=NULL;} + if (_failureCallbackQueue) { dispatch_release(_failureCallbackQueue), _failureCallbackQueue=NULL;} [super dealloc]; } @@ -85,6 +90,34 @@ return !self.acceptableContentTypes || [self.acceptableContentTypes containsObject:[self.response MIMEType]]; } +- (void)setSuccessCallbackQueue:(dispatch_queue_t)successCallbackQueue { + if (successCallbackQueue != _successCallbackQueue) { + + if (_successCallbackQueue) { + dispatch_release(_successCallbackQueue); + } + + if (successCallbackQueue) { + dispatch_retain(successCallbackQueue); + _successCallbackQueue = successCallbackQueue; + } + } +} + +- (void)setFailureCallbackQueue:(dispatch_queue_t)failureCallbackQueue { + if (failureCallbackQueue != _failureCallbackQueue) { + + if (_failureCallbackQueue) { + dispatch_release(_failureCallbackQueue); + } + + if (failureCallbackQueue) { + dispatch_retain(failureCallbackQueue); + _failureCallbackQueue = failureCallbackQueue; + } + } +} + - (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { @@ -95,13 +128,13 @@ if (self.error) { if (failure) { - dispatch_async(dispatch_get_main_queue(), ^(void) { + dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ failure(self, self.error); }); } } else { if (success) { - dispatch_async(dispatch_get_main_queue(), ^{ + dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ success(self, self.responseData); }); } diff --git a/AFNetworking/AFImageRequestOperation.m b/AFNetworking/AFImageRequestOperation.m index e004e9d..d1f4d2b 100644 --- a/AFNetworking/AFImageRequestOperation.m +++ b/AFNetworking/AFImageRequestOperation.m @@ -231,13 +231,13 @@ static dispatch_queue_t image_request_operation_processing_queue() { dispatch_async(image_request_operation_processing_queue(), ^(void) { if (self.error) { if (failure) { - dispatch_async(dispatch_get_main_queue(), ^(void) { + dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ failure(self, self.error); }); } } else { if (success) { - dispatch_async(dispatch_get_main_queue(), ^(void) { + dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ success(self, self.responseImage); }); } diff --git a/AFNetworking/AFJSONRequestOperation.m b/AFNetworking/AFJSONRequestOperation.m index 5c651de..cc7d661 100644 --- a/AFNetworking/AFJSONRequestOperation.m +++ b/AFNetworking/AFJSONRequestOperation.m @@ -125,7 +125,7 @@ static dispatch_queue_t json_request_operation_processing_queue() { if (self.error) { if (failure) { - dispatch_async(dispatch_get_main_queue(), ^(void) { + dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ failure(self, self.error); }); } @@ -133,17 +133,19 @@ static dispatch_queue_t json_request_operation_processing_queue() { dispatch_async(json_request_operation_processing_queue(), ^(void) { id JSON = self.responseJSON; - dispatch_async(dispatch_get_main_queue(), ^(void) { - if (self.JSONError) { - if (failure) { + if (self.JSONError) { + if (failure) { + dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ failure(self, self.JSONError); - } - } else { - if (success) { - success(self, JSON); - } + }); } - }); + } else { + if (success) { + dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ + success(self, JSON); + }); + } + } }); } }; diff --git a/AFNetworking/AFPropertyListRequestOperation.m b/AFNetworking/AFPropertyListRequestOperation.m index bb7a41b..0fcade0 100644 --- a/AFNetworking/AFPropertyListRequestOperation.m +++ b/AFNetworking/AFPropertyListRequestOperation.m @@ -125,7 +125,7 @@ static dispatch_queue_t property_list_request_operation_processing_queue() { if (self.error) { if (failure) { - dispatch_async(dispatch_get_main_queue(), ^(void) { + dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ failure(self, self.error); }); } @@ -133,7 +133,7 @@ static dispatch_queue_t property_list_request_operation_processing_queue() { dispatch_async(property_list_request_operation_processing_queue(), ^(void) { id propertyList = self.responsePropertyList; - dispatch_async(dispatch_get_main_queue(), ^(void) { + dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ if (self.propertyListError) { if (failure) { failure(self, self.propertyListError); diff --git a/AFNetworking/AFXMLRequestOperation.m b/AFNetworking/AFXMLRequestOperation.m index b6b3a2b..ee7865a 100644 --- a/AFNetworking/AFXMLRequestOperation.m +++ b/AFNetworking/AFXMLRequestOperation.m @@ -188,13 +188,15 @@ static dispatch_queue_t xml_request_operation_processing_queue() { if (self.error) { if (failure) { - dispatch_async(dispatch_get_main_queue(), ^(void) { + dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ failure(self, self.error); }); } } else { if (success) { - success(self, self.responseXMLParser); + dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ + success(self, self.responseXMLParser); + }); } } }; From 30a5cea4fcd443825608c28ef88b5b336cfc46f3 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 6 Feb 2012 13:43:43 -0800 Subject: [PATCH 2/4] Added methods to simplify calling the success/failure handlers. --- AFNetworking/AFHTTPRequestOperation.h | 15 +++++++++ AFNetworking/AFHTTPRequestOperation.m | 33 ++++++++++++------- AFNetworking/AFImageRequestOperation.m | 14 ++------ AFNetworking/AFJSONRequestOperation.m | 12 ++----- AFNetworking/AFPropertyListRequestOperation.m | 24 ++++---------- AFNetworking/AFXMLRequestOperation.m | 12 ++----- 6 files changed, 51 insertions(+), 59 deletions(-) diff --git a/AFNetworking/AFHTTPRequestOperation.h b/AFNetworking/AFHTTPRequestOperation.h index 235cc1a..7c3d234 100644 --- a/AFNetworking/AFHTTPRequestOperation.h +++ b/AFNetworking/AFHTTPRequestOperation.h @@ -107,3 +107,18 @@ failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; @end + + +@interface AFHTTPRequestOperation (AFInternal) + +/** + Executes the successBlock on the corresponding successCallbackQueue. + */ +- (void)dispatchSuccessBlock:(void (^)(AFHTTPRequestOperation *operation, id responseObject))successBlock responseObject:(id)responseObject; + +/** + Executes the failureBlock on the corresponding failureCallbackQueue. + */ +- (void)dispatchFailureBlock:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failureBlock error:(NSError *)error; + +@end \ No newline at end of file diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 2fa2326..6f72918 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -127,17 +127,9 @@ } if (self.error) { - if (failure) { - dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ - failure(self, self.error); - }); - } + [self dispatchFailureBlock:failure error:self.error]; } else { - if (success) { - dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ - success(self, self.responseData); - }); - } + [self dispatchSuccessBlock:success responseObject:self.responseString]; } }; } @@ -146,6 +138,25 @@ + (BOOL)canProcessRequest:(NSURLRequest *)request { return YES; -} +} + +#pragma mark - AFInternal + +- (void)dispatchSuccessBlock:(void (^)(AFHTTPRequestOperation *operation, id responseObject))successBlock responseObject:(id)responseObject { + if (successBlock) { + dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ + successBlock(self, responseObject); + }); + } +} + +- (void)dispatchFailureBlock:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failureBlock error:(NSError *)error { + if (failureBlock) { + dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ + failureBlock(self, error); + }); + + } +} @end diff --git a/AFNetworking/AFImageRequestOperation.m b/AFNetworking/AFImageRequestOperation.m index d1f4d2b..554f6b7 100644 --- a/AFNetworking/AFImageRequestOperation.m +++ b/AFNetworking/AFImageRequestOperation.m @@ -230,17 +230,9 @@ static dispatch_queue_t image_request_operation_processing_queue() { dispatch_async(image_request_operation_processing_queue(), ^(void) { if (self.error) { - if (failure) { - dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ - failure(self, self.error); - }); - } - } else { - if (success) { - dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ - success(self, self.responseImage); - }); - } + [self dispatchFailureBlock:failure error:self.error]; + } else { + [self dispatchSuccessBlock:success responseObject:self.responseImage]; } }); }; diff --git a/AFNetworking/AFJSONRequestOperation.m b/AFNetworking/AFJSONRequestOperation.m index cc7d661..07e6113 100644 --- a/AFNetworking/AFJSONRequestOperation.m +++ b/AFNetworking/AFJSONRequestOperation.m @@ -134,17 +134,9 @@ static dispatch_queue_t json_request_operation_processing_queue() { id JSON = self.responseJSON; if (self.JSONError) { - if (failure) { - dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ - failure(self, self.JSONError); - }); - } + [self dispatchFailureBlock:failure error:self.JSONError]; } else { - if (success) { - dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ - success(self, JSON); - }); - } + [self dispatchSuccessBlock:success responseObject:JSON]; } }); } diff --git a/AFNetworking/AFPropertyListRequestOperation.m b/AFNetworking/AFPropertyListRequestOperation.m index 0fcade0..b65692e 100644 --- a/AFNetworking/AFPropertyListRequestOperation.m +++ b/AFNetworking/AFPropertyListRequestOperation.m @@ -124,26 +124,16 @@ static dispatch_queue_t property_list_request_operation_processing_queue() { } if (self.error) { - if (failure) { - dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ - failure(self, self.error); - }); - } + [self dispatchFailureBlock:failure error:self.error]; } else { dispatch_async(property_list_request_operation_processing_queue(), ^(void) { id propertyList = self.responsePropertyList; - - dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ - if (self.propertyListError) { - if (failure) { - failure(self, self.propertyListError); - } - } else { - if (success) { - success(self, propertyList); - } - } - }); + + if (self.propertyListError) { + [self dispatchFailureBlock:failure error:self.propertyListError]; + }else { + [self dispatchSuccessBlock:success responseObject:propertyList]; + } }); } }; diff --git a/AFNetworking/AFXMLRequestOperation.m b/AFNetworking/AFXMLRequestOperation.m index ee7865a..f3966c4 100644 --- a/AFNetworking/AFXMLRequestOperation.m +++ b/AFNetworking/AFXMLRequestOperation.m @@ -187,17 +187,9 @@ static dispatch_queue_t xml_request_operation_processing_queue() { } if (self.error) { - if (failure) { - dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ - failure(self, self.error); - }); - } + [self dispatchFailureBlock:failure error:self.error]; } else { - if (success) { - dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ - success(self, self.responseXMLParser); - }); - } + [self dispatchSuccessBlock:success responseObject:self.responseXMLParser]; } }; } From 800d05181deaa18506c26231b145f0a448b44a25 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 8 Feb 2012 15:04:29 -0800 Subject: [PATCH 3/4] Simplify dispatchFailureBlock As error is overridden to always return the custom error object we can omit the extra error: parameter in dispatchFailureBlock, making the code even simpler. --- AFNetworking/AFHTTPRequestOperation.h | 2 +- AFNetworking/AFHTTPRequestOperation.m | 7 +++---- AFNetworking/AFImageRequestOperation.m | 2 +- AFNetworking/AFJSONRequestOperation.m | 2 +- AFNetworking/AFPropertyListRequestOperation.m | 4 ++-- AFNetworking/AFXMLRequestOperation.m | 2 +- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/AFNetworking/AFHTTPRequestOperation.h b/AFNetworking/AFHTTPRequestOperation.h index 7c3d234..ea6bfd0 100644 --- a/AFNetworking/AFHTTPRequestOperation.h +++ b/AFNetworking/AFHTTPRequestOperation.h @@ -119,6 +119,6 @@ /** Executes the failureBlock on the corresponding failureCallbackQueue. */ -- (void)dispatchFailureBlock:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failureBlock error:(NSError *)error; +- (void)dispatchFailureBlock:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failureBlock; @end \ No newline at end of file diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 6f72918..591c56e 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -127,7 +127,7 @@ } if (self.error) { - [self dispatchFailureBlock:failure error:self.error]; + [self dispatchFailureBlock:failure]; } else { [self dispatchSuccessBlock:success responseObject:self.responseString]; } @@ -150,12 +150,11 @@ } } -- (void)dispatchFailureBlock:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failureBlock error:(NSError *)error { +- (void)dispatchFailureBlock:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failureBlock { if (failureBlock) { dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ - failureBlock(self, error); + failureBlock(self, self.error); }); - } } diff --git a/AFNetworking/AFImageRequestOperation.m b/AFNetworking/AFImageRequestOperation.m index 554f6b7..091f571 100644 --- a/AFNetworking/AFImageRequestOperation.m +++ b/AFNetworking/AFImageRequestOperation.m @@ -230,7 +230,7 @@ static dispatch_queue_t image_request_operation_processing_queue() { dispatch_async(image_request_operation_processing_queue(), ^(void) { if (self.error) { - [self dispatchFailureBlock:failure error:self.error]; + [self dispatchFailureBlock:failure]; } else { [self dispatchSuccessBlock:success responseObject:self.responseImage]; } diff --git a/AFNetworking/AFJSONRequestOperation.m b/AFNetworking/AFJSONRequestOperation.m index 07e6113..13bfd74 100644 --- a/AFNetworking/AFJSONRequestOperation.m +++ b/AFNetworking/AFJSONRequestOperation.m @@ -134,7 +134,7 @@ static dispatch_queue_t json_request_operation_processing_queue() { id JSON = self.responseJSON; if (self.JSONError) { - [self dispatchFailureBlock:failure error:self.JSONError]; + [self dispatchFailureBlock:failure]; } else { [self dispatchSuccessBlock:success responseObject:JSON]; } diff --git a/AFNetworking/AFPropertyListRequestOperation.m b/AFNetworking/AFPropertyListRequestOperation.m index b65692e..d294cd2 100644 --- a/AFNetworking/AFPropertyListRequestOperation.m +++ b/AFNetworking/AFPropertyListRequestOperation.m @@ -124,13 +124,13 @@ static dispatch_queue_t property_list_request_operation_processing_queue() { } if (self.error) { - [self dispatchFailureBlock:failure error:self.error]; + [self dispatchFailureBlock:failure]; } else { dispatch_async(property_list_request_operation_processing_queue(), ^(void) { id propertyList = self.responsePropertyList; if (self.propertyListError) { - [self dispatchFailureBlock:failure error:self.propertyListError]; + [self dispatchFailureBlock:failure]; }else { [self dispatchSuccessBlock:success responseObject:propertyList]; } diff --git a/AFNetworking/AFXMLRequestOperation.m b/AFNetworking/AFXMLRequestOperation.m index f3966c4..7b50fd6 100644 --- a/AFNetworking/AFXMLRequestOperation.m +++ b/AFNetworking/AFXMLRequestOperation.m @@ -187,7 +187,7 @@ static dispatch_queue_t xml_request_operation_processing_queue() { } if (self.error) { - [self dispatchFailureBlock:failure error:self.error]; + [self dispatchFailureBlock:failure]; } else { [self dispatchSuccessBlock:success responseObject:self.responseXMLParser]; } From 28e580c9611c66c76125678b9f354cac2b0df392 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 8 Feb 2012 15:05:19 -0800 Subject: [PATCH 4/4] Replaces a failure block with dispatchFailureBlock method I missed that on the initial transform. --- AFNetworking/AFJSONRequestOperation.m | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/AFNetworking/AFJSONRequestOperation.m b/AFNetworking/AFJSONRequestOperation.m index 13bfd74..6d39413 100644 --- a/AFNetworking/AFJSONRequestOperation.m +++ b/AFNetworking/AFJSONRequestOperation.m @@ -124,11 +124,7 @@ static dispatch_queue_t json_request_operation_processing_queue() { } if (self.error) { - if (failure) { - dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ - failure(self, self.error); - }); - } + [self dispatchFailureBlock:failure]; } else { dispatch_async(json_request_operation_processing_queue(), ^(void) { id JSON = self.responseJSON;