Merge branch 'experimental-http-client-callback-refactoring' into experimental-0.8

This commit is contained in:
Mattt Thompson 2011-11-07 11:20:15 -06:00
commit 200512c7b3
12 changed files with 227 additions and 221 deletions

View file

@ -125,20 +125,20 @@ typedef enum {
///---------------------------------- ///----------------------------------
/** /**
Attempts to register a class conforming to the `AFHTTPClientOperation` protocol, adding it to a chain to automatically generate request operations from a URL request. Attempts to register a subclass of `AFHTTPRequestOperation`, adding it to a chain to automatically generate request operations from a URL request.
@param The class conforming to the `AFHTTPClientOperation` protocol to register @param The subclass of `AFHTTPRequestOperation` to register
@return `YES` if the registration is successful, `NO` otherwise. The only failure condition is if `operationClass` does not conform to the `AFHTTPCLientOperation` protocol. @return `YES` if the registration is successful, `NO` otherwise. The only failure condition is if `operationClass` does is not a subclass of `AFHTTPRequestOperation`.
@discussion When `enqueueHTTPRequestOperationWithRequest:success:failure` is invoked, each registered class is consulted in turn to see if it can handle the specific request. The first class to return `YES` when sent a `canProcessRequest:` message is used to generate an operation using `HTTPRequestOperationWithRequest:success:failure:`. There is no guarantee that all registered classes will be consulted. Classes are consulted in the reverse order of their registration. Attempting to register an already-registered class will move it to the top of the chain. @discussion When `enqueueHTTPRequestOperationWithRequest:success:failure` is invoked, each registered class is consulted in turn to see if it can handle the specific request. The first class to return `YES` when sent a `canProcessRequest:` message is used to create an operation using `initWithURLRequest:` and do `setCompletionBlockWithSuccess:failure:`. There is no guarantee that all registered classes will be consulted. Classes are consulted in the reverse order of their registration. Attempting to register an already-registered class will move it to the top of the list.
@see `AFHTTPClientOperation` @see `AFHTTPClientOperation`
*/ */
- (BOOL)registerHTTPOperationClass:(Class)operationClass; - (BOOL)registerHTTPOperationClass:(Class)operationClass;
/** /**
Unregisteres the specified class conforming to the `AFHTTPClientOperation` protocol. Unregisters the specified subclass of `AFHTTPRequestOperation`.
@param The class conforming to the `AFHTTPClientOperation` protocol to unregister @param The class conforming to the `AFHTTPClientOperation` protocol to unregister
@ -244,8 +244,8 @@ typedef enum {
@see `AFHTTPClientOperation` @see `AFHTTPClientOperation`
*/ */
- (void)enqueueHTTPRequestOperationWithRequest:(NSURLRequest *)request - (void)enqueueHTTPRequestOperationWithRequest:(NSURLRequest *)request
success:(void (^)(id object))success success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure; failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
/** /**
Enqueues an `AFHTTPRequestOperation` to the HTTP client's operation queue. Enqueues an `AFHTTPRequestOperation` to the HTTP client's operation queue.
@ -281,8 +281,8 @@ typedef enum {
*/ */
- (void)getPath:(NSString *)path - (void)getPath:(NSString *)path
parameters:(NSDictionary *)parameters parameters:(NSDictionary *)parameters
success:(void (^)(id object))success success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure; failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
/** /**
Creates an `AFHTTPRequestOperation` with a `POST` request, and enqueues it to the HTTP client's operation queue. Creates an `AFHTTPRequestOperation` with a `POST` request, and enqueues it to the HTTP client's operation queue.
@ -296,8 +296,8 @@ typedef enum {
*/ */
- (void)postPath:(NSString *)path - (void)postPath:(NSString *)path
parameters:(NSDictionary *)parameters parameters:(NSDictionary *)parameters
success:(void (^)(id object))success success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure; failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
/** /**
Creates an `AFHTTPRequestOperation` with a `PUT` request, and enqueues it to the HTTP client's operation queue. Creates an `AFHTTPRequestOperation` with a `PUT` request, and enqueues it to the HTTP client's operation queue.
@ -311,8 +311,8 @@ typedef enum {
*/ */
- (void)putPath:(NSString *)path - (void)putPath:(NSString *)path
parameters:(NSDictionary *)parameters parameters:(NSDictionary *)parameters
success:(void (^)(id object))success success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure; failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
/** /**
Creates an `AFHTTPRequestOperation` with a `DELETE` request, and enqueues it to the HTTP client's operation queue. Creates an `AFHTTPRequestOperation` with a `DELETE` request, and enqueues it to the HTTP client's operation queue.
@ -326,36 +326,8 @@ typedef enum {
*/ */
- (void)deletePath:(NSString *)path - (void)deletePath:(NSString *)path
parameters:(NSDictionary *)parameters parameters:(NSDictionary *)parameters
success:(void (^)(id object))success success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure; failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
@end
#pragma mark -
/**
The `AFHTTPClientOperation` protocol defines the methods used for the automatic content parsing functionality of `AFHTTPClient`.
@see `AFHTTPClient -registerHTTPOperationClass:`
*/
@protocol AFHTTPClientOperation
/**
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`.
@param urlRequest The request that is determined to be supported or not supported for this class.
*/
+ (BOOL)canProcessRequest:(NSURLRequest *)urlRequest;
/**
Constructs and initializes an operation with success and failure callbacks.
@param urlRequest The request used by the operation connection.
@param success A block object to be executed when the operation finishes successfully. The block has no return value and takes a single argument, the response object from the request.
@param failure A block object to be executed when the operation finishes unsuccessfully. The block has no return value and takes two arguments: the response received from the server, and the error describing the network or parsing error that occurred.
*/
+ (id)HTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(id object))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure;
@end @end
#pragma mark - #pragma mark -

View file

@ -208,7 +208,7 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
#pragma mark - #pragma mark -
- (BOOL)registerHTTPOperationClass:(Class)operationClass { - (BOOL)registerHTTPOperationClass:(Class)operationClass {
if (![operationClass conformsToProtocol:@protocol(AFHTTPClientOperation)]) { if (![operationClass isSubclassOfClass:[AFHTTPRequestOperation class]]) {
return NO; return NO;
} }
@ -325,8 +325,8 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
} }
- (void)enqueueHTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest - (void)enqueueHTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(id object))success success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{ {
AFHTTPRequestOperation *operation = nil; AFHTTPRequestOperation *operation = nil;
NSString *className = nil; NSString *className = nil;
@ -334,13 +334,15 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
while (!operation && (className = [enumerator nextObject])) { while (!operation && (className = [enumerator nextObject])) {
Class class = NSClassFromString(className); Class class = NSClassFromString(className);
if (class && [class canProcessRequest:urlRequest]) { if (class && [class canProcessRequest:urlRequest]) {
operation = [class HTTPRequestOperationWithRequest:urlRequest success:success failure:failure]; operation = [[(AFHTTPRequestOperation *)[class alloc] initWithRequest:urlRequest] autorelease];
} }
} }
if (!operation) { if (!operation) {
operation = [AFHTTPRequestOperation HTTPRequestOperationWithRequest:urlRequest success:success failure:failure]; operation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
} }
[operation setCompletionBlockWithSuccess:success failure:failure];
[self enqueueHTTPRequestOperation:operation]; [self enqueueHTTPRequestOperation:operation];
} }
@ -361,8 +363,8 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
- (void)getPath:(NSString *)path - (void)getPath:(NSString *)path
parameters:(NSDictionary *)parameters parameters:(NSDictionary *)parameters
success:(void (^)(id object))success success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{ {
NSURLRequest *request = [self requestWithMethod:@"GET" path:path parameters:parameters]; NSURLRequest *request = [self requestWithMethod:@"GET" path:path parameters:parameters];
[self enqueueHTTPRequestOperationWithRequest:request success:success failure:failure]; [self enqueueHTTPRequestOperationWithRequest:request success:success failure:failure];
@ -370,8 +372,8 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
- (void)postPath:(NSString *)path - (void)postPath:(NSString *)path
parameters:(NSDictionary *)parameters parameters:(NSDictionary *)parameters
success:(void (^)(id object))success success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{ {
NSURLRequest *request = [self requestWithMethod:@"POST" path:path parameters:parameters]; NSURLRequest *request = [self requestWithMethod:@"POST" path:path parameters:parameters];
[self enqueueHTTPRequestOperationWithRequest:request success:success failure:failure]; [self enqueueHTTPRequestOperationWithRequest:request success:success failure:failure];
@ -379,8 +381,8 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
- (void)putPath:(NSString *)path - (void)putPath:(NSString *)path
parameters:(NSDictionary *)parameters parameters:(NSDictionary *)parameters
success:(void (^)(id object))success success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{ {
NSURLRequest *request = [self requestWithMethod:@"PUT" path:path parameters:parameters]; NSURLRequest *request = [self requestWithMethod:@"PUT" path:path parameters:parameters];
[self enqueueHTTPRequestOperationWithRequest:request success:success failure:failure]; [self enqueueHTTPRequestOperationWithRequest:request success:success failure:failure];
@ -388,8 +390,8 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
- (void)deletePath:(NSString *)path - (void)deletePath:(NSString *)path
parameters:(NSDictionary *)parameters parameters:(NSDictionary *)parameters
success:(void (^)(id object))success success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{ {
NSURLRequest *request = [self requestWithMethod:@"DELETE" path:path parameters:parameters]; NSURLRequest *request = [self requestWithMethod:@"DELETE" path:path parameters:parameters];
[self enqueueHTTPRequestOperationWithRequest:request success:success failure:failure]; [self enqueueHTTPRequestOperationWithRequest:request success:success failure:failure];

View file

@ -22,12 +22,11 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "AFURLConnectionOperation.h" #import "AFURLConnectionOperation.h"
#import "AFHTTPClient.h"
/** /**
`AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request. `AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request.
*/ */
@interface AFHTTPRequestOperation : AFURLConnectionOperation <AFHTTPClientOperation> { @interface AFHTTPRequestOperation : AFURLConnectionOperation {
@private @private
NSIndexSet *_acceptableStatusCodes; NSIndexSet *_acceptableStatusCodes;
NSSet *_acceptableContentTypes; NSSet *_acceptableContentTypes;
@ -72,4 +71,21 @@
*/ */
@property (readonly) BOOL hasAcceptableContentType; @property (readonly) BOOL hasAcceptableContentType;
/**
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`.
@param urlRequest The request that is determined to be supported or not supported for this class.
*/
+ (BOOL)canProcessRequest:(NSURLRequest *)urlRequest;
///-----------------------------------------------------------
/// @name Setting Completion Block Success / Failure Callbacks
///-----------------------------------------------------------
/**
*/
- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
@end @end

View file

@ -23,14 +23,14 @@
#import "AFHTTPRequestOperation.h" #import "AFHTTPRequestOperation.h"
@interface AFHTTPRequestOperation () @interface AFHTTPRequestOperation ()
@property (readwrite, nonatomic, retain) NSError *error; @property (readwrite, nonatomic, retain) NSError *HTTPError;
@property (readonly, nonatomic, assign) BOOL hasContent; @property (readonly, nonatomic, assign) BOOL hasContent;
@end @end
@implementation AFHTTPRequestOperation @implementation AFHTTPRequestOperation
@synthesize acceptableStatusCodes = _acceptableStatusCodes; @synthesize acceptableStatusCodes = _acceptableStatusCodes;
@synthesize acceptableContentTypes = _acceptableContentTypes; @synthesize acceptableContentTypes = _acceptableContentTypes;
@synthesize error = _HTTPError; @synthesize HTTPError = _HTTPError;
- (id)initWithRequest:(NSURLRequest *)request { - (id)initWithRequest:(NSURLRequest *)request {
self = [super initWithRequest:request]; self = [super initWithRequest:request];
@ -55,23 +55,27 @@
} }
- (NSError *)error { - (NSError *)error {
if (self.response) { if (self.response && !self.HTTPError) {
if (![self hasAcceptableStatusCode]) { if (![self hasAcceptableStatusCode]) {
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
[userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected status code %@, got %d", nil), self.acceptableStatusCodes, [self.response statusCode]] forKey:NSLocalizedDescriptionKey]; [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected status code %@, got %d", nil), self.acceptableStatusCodes, [self.response statusCode]] forKey:NSLocalizedDescriptionKey];
[userInfo setValue:[self.request URL] forKey:NSURLErrorFailingURLErrorKey]; [userInfo setValue:[self.request URL] forKey:NSURLErrorFailingURLErrorKey];
self.error = [[[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadServerResponse userInfo:userInfo] autorelease]; self.HTTPError = [[[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadServerResponse userInfo:userInfo] autorelease];
} else if ([self hasContent] && ![self hasAcceptableContentType]) { // Don't invalidate content type if there is no content } else if ([self hasContent] && ![self hasAcceptableContentType]) { // Don't invalidate content type if there is no content
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
[userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected content type %@, got %@", nil), self.acceptableContentTypes, [self.response MIMEType]] forKey:NSLocalizedDescriptionKey]; [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected content type %@, got %@", nil), self.acceptableContentTypes, [self.response MIMEType]] forKey:NSLocalizedDescriptionKey];
[userInfo setValue:[self.request URL] forKey:NSURLErrorFailingURLErrorKey]; [userInfo setValue:[self.request URL] forKey:NSURLErrorFailingURLErrorKey];
self.error = [[[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo] autorelease]; self.HTTPError = [[[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo] autorelease];
} }
} }
return _HTTPError; if (_HTTPError) {
return _HTTPError;
} else {
return [super error];
}
} }
- (BOOL)hasContent { - (BOOL)hasContent {
@ -86,38 +90,34 @@
return !self.acceptableContentTypes || [self.acceptableContentTypes containsObject:[self.response MIMEType]]; return !self.acceptableContentTypes || [self.acceptableContentTypes containsObject:[self.response MIMEType]];
} }
#pragma mark - AFHTTPClientOperation - (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
+ (BOOL)canProcessRequest:(NSURLRequest *)request {
return NO;
}
+ (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(id object))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
{ {
AFHTTPRequestOperation *operation = [[[self alloc] initWithRequest:urlRequest] autorelease]; self.completionBlock = ^ {
operation.completionBlock = ^ { if ([self isCancelled]) {
if ([operation isCancelled]) {
return; return;
} }
if (operation.error) { if (self.error) {
if (failure) { if (failure) {
dispatch_async(dispatch_get_main_queue(), ^(void) { dispatch_async(dispatch_get_main_queue(), ^(void) {
failure(operation.response, operation.error); failure(self, self.error);
}); });
} }
} else { } else {
if (success) { if (success) {
dispatch_async(dispatch_get_main_queue(), ^(void) { dispatch_async(dispatch_get_main_queue(), ^{
success(operation.responseData); success(self, self.responseData);
}); });
} }
} }
}; };
}
return operation;
} #pragma mark - AFHTTPClientOperation
+ (BOOL)canProcessRequest:(NSURLRequest *)request {
return YES;
}
@end @end

View file

@ -62,6 +62,6 @@
@return A new JSON request operation @return A new JSON request operation
*/ */
+ (AFJSONRequestOperation *)JSONRequestOperationWithRequest:(NSURLRequest *)urlRequest + (AFJSONRequestOperation *)JSONRequestOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, id JSON))success success:(void (^)(NSURLRequest *request, NSURLResponse *response, id JSON))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure; failure:(void (^)(NSURLRequest *request, NSURLResponse *response, NSError *error, id JSON))failure;
@end @end

View file

@ -48,41 +48,21 @@ static dispatch_queue_t json_request_operation_processing_queue() {
@synthesize JSONError = _JSONError; @synthesize JSONError = _JSONError;
+ (AFJSONRequestOperation *)JSONRequestOperationWithRequest:(NSURLRequest *)urlRequest + (AFJSONRequestOperation *)JSONRequestOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, id JSON))success success:(void (^)(NSURLRequest *request, NSURLResponse *response, id JSON))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure failure:(void (^)(NSURLRequest *request, NSURLResponse *response, NSError *error, id JSON))failure
{ {
AFJSONRequestOperation *operation = [[[self alloc] initWithRequest:urlRequest] autorelease]; AFJSONRequestOperation *requestOperation = [[[self alloc] initWithRequest:urlRequest] autorelease];
operation.completionBlock = ^ { [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([operation isCancelled]) { if (success) {
return; success(operation.request, operation.response, responseObject);
} }
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (operation.error) { if (failure) {
if (failure) { failure(operation.request, operation.response, error, [(AFJSONRequestOperation *)operation responseJSON]);
dispatch_async(dispatch_get_main_queue(), ^(void) {
failure(operation.request, operation.response, operation.error);
});
}
} else {
dispatch_async(json_request_operation_processing_queue(), ^(void) {
id JSON = operation.responseJSON;
dispatch_async(dispatch_get_main_queue(), ^(void) {
if (operation.error) {
if (failure) {
failure(operation.request, operation.response, operation.error);
}
} else {
if (success) {
success(operation.request, operation.response, JSON);
}
}
});
});
} }
}; }];
return operation; return requestOperation;
} }
+ (NSSet *)defaultAcceptableContentTypes { + (NSSet *)defaultAcceptableContentTypes {
@ -93,6 +73,10 @@ static dispatch_queue_t json_request_operation_processing_queue() {
return [NSSet setWithObjects:@"json", nil]; return [NSSet setWithObjects:@"json", nil];
} }
+ (BOOL)canProcessRequest:(NSURLRequest *)request {
return [[self defaultAcceptableContentTypes] containsObject:[request valueForHTTPHeaderField:@"Accept"]] || [[self defaultAcceptablePathExtensions] containsObject:[[request URL] pathExtension]];
}
- (id)initWithRequest:(NSURLRequest *)urlRequest { - (id)initWithRequest:(NSURLRequest *)urlRequest {
self = [super initWithRequest:urlRequest]; self = [super initWithRequest:urlRequest];
if (!self) { if (!self) {
@ -143,21 +127,38 @@ static dispatch_queue_t json_request_operation_processing_queue() {
} }
} }
#pragma mark - AFHTTPClientOperation - (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
+ (BOOL)canProcessRequest:(NSURLRequest *)request {
return [[self defaultAcceptableContentTypes] containsObject:[request valueForHTTPHeaderField:@"Accept"]] || [[self defaultAcceptablePathExtensions] containsObject:[[request URL] pathExtension]];
}
+ (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(id object))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
{ {
return [self JSONRequestOperationWithRequest:urlRequest success:^(NSURLRequest __unused *request, NSHTTPURLResponse __unused *response, id JSON) { self.completionBlock = ^ {
success(JSON); if ([self isCancelled]) {
} failure:^(NSURLRequest __unused *request, NSHTTPURLResponse *response, NSError *error) { return;
failure(response, error); }
}];
if (self.error) {
if (failure) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
failure(self, self.error);
});
}
} else {
dispatch_async(json_request_operation_processing_queue(), ^(void) {
id JSON = self.responseJSON;
dispatch_async(dispatch_get_main_queue(), ^(void) {
if (self.JSONError) {
if (failure) {
failure(self, self.JSONError);
}
} else {
if (success) {
success(self, JSON);
}
}
});
});
}
};
} }
@end @end

View file

@ -69,6 +69,6 @@
*/ */
+ (AFPropertyListRequestOperation *)propertyListRequestOperationWithRequest:(NSURLRequest *)request + (AFPropertyListRequestOperation *)propertyListRequestOperationWithRequest:(NSURLRequest *)request
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, id propertyList))success success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, id propertyList))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure; failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id propertyList))failure;
@end @end

View file

@ -34,7 +34,7 @@ static dispatch_queue_t property_list_request_operation_processing_queue() {
@interface AFPropertyListRequestOperation () @interface AFPropertyListRequestOperation ()
@property (readwrite, nonatomic, retain) id responsePropertyList; @property (readwrite, nonatomic, retain) id responsePropertyList;
@property (readwrite, nonatomic, assign) NSPropertyListFormat propertyListFormat; @property (readwrite, nonatomic, assign) NSPropertyListFormat propertyListFormat;
@property (readwrite, nonatomic, retain) NSError *error; @property (readwrite, nonatomic, retain) NSError *propertyListError;
+ (NSSet *)defaultAcceptableContentTypes; + (NSSet *)defaultAcceptableContentTypes;
+ (NSSet *)defaultAcceptablePathExtensions; + (NSSet *)defaultAcceptablePathExtensions;
@ -44,44 +44,24 @@ static dispatch_queue_t property_list_request_operation_processing_queue() {
@synthesize responsePropertyList = _responsePropertyList; @synthesize responsePropertyList = _responsePropertyList;
@synthesize propertyListReadOptions = _propertyListReadOptions; @synthesize propertyListReadOptions = _propertyListReadOptions;
@synthesize propertyListFormat = _propertyListFormat; @synthesize propertyListFormat = _propertyListFormat;
@synthesize error = _propertyListError; @synthesize propertyListError = _propertyListError;
+ (AFPropertyListRequestOperation *)propertyListRequestOperationWithRequest:(NSURLRequest *)request + (AFPropertyListRequestOperation *)propertyListRequestOperationWithRequest:(NSURLRequest *)request
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, id propertyList))success success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, id propertyList))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id propertyList))failure
{ {
AFPropertyListRequestOperation *operation = [[[self alloc] initWithRequest:request] autorelease]; AFPropertyListRequestOperation *requestOperation = [[[self alloc] initWithRequest:request] autorelease];
operation.completionBlock = ^ { [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([operation isCancelled]) { if (success) {
return; success(operation.request, operation.response, responseObject);
} }
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (operation.error) { if (failure) {
if (failure) { failure(operation.request, operation.response, error, [(AFPropertyListRequestOperation *)operation responsePropertyList]);
dispatch_async(dispatch_get_main_queue(), ^(void) {
failure(operation.request, operation.response, operation.error);
});
}
} else {
dispatch_async(property_list_request_operation_processing_queue(), ^(void) {
id propertyList = operation.responsePropertyList;
dispatch_async(dispatch_get_main_queue(), ^(void) {
if (operation.error) {
if (failure) {
failure(operation.request, operation.response, operation.error);
}
} else {
if (success) {
success(operation.request, operation.response, propertyList);
}
}
});
});
} }
}; }];
return operation; return requestOperation;
} }
+ (NSSet *)defaultAcceptableContentTypes { + (NSSet *)defaultAcceptableContentTypes {
@ -117,27 +97,56 @@ static dispatch_queue_t property_list_request_operation_processing_queue() {
NSError *error = nil; NSError *error = nil;
self.responsePropertyList = [NSPropertyListSerialization propertyListWithData:self.responseData options:self.propertyListReadOptions format:&format error:&error]; self.responsePropertyList = [NSPropertyListSerialization propertyListWithData:self.responseData options:self.propertyListReadOptions format:&format error:&error];
self.propertyListFormat = format; self.propertyListFormat = format;
self.error = error; self.propertyListError = error;
} }
return _responsePropertyList; return _responsePropertyList;
} }
#pragma mark - AFHTTPClientOperation - (NSError *)error {
if (_propertyListError) {
return _propertyListError;
} else {
return [super error];
}
}
+ (BOOL)canProcessRequest:(NSURLRequest *)request { + (BOOL)canProcessRequest:(NSURLRequest *)request {
return [[self defaultAcceptableContentTypes] containsObject:[request valueForHTTPHeaderField:@"Accept"]] || [[self defaultAcceptablePathExtensions] containsObject:[[request URL] pathExtension]]; return [[self defaultAcceptableContentTypes] containsObject:[request valueForHTTPHeaderField:@"Accept"]] || [[self defaultAcceptablePathExtensions] containsObject:[[request URL] pathExtension]];
} }
+ (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest - (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
success:(void (^)(id object))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
{ {
return [self propertyListRequestOperationWithRequest:urlRequest success:^(NSURLRequest __unused *request, NSHTTPURLResponse __unused *response, id propertyList) { self.completionBlock = ^ {
success(propertyList); if ([self isCancelled]) {
} failure:^(NSURLRequest __unused *request, NSHTTPURLResponse *response, NSError *error) { return;
failure(response, error); }
}];
if (self.error) {
if (failure) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
failure(self, self.error);
});
}
} else {
dispatch_async(property_list_request_operation_processing_queue(), ^(void) {
id propertyList = self.responsePropertyList;
dispatch_async(dispatch_get_main_queue(), ^(void) {
if (self.propertyListError) {
if (failure) {
failure(self, self.propertyListError);
}
} else {
if (success) {
success(self, propertyList);
}
}
});
});
}
};
} }
@end @end

View file

@ -71,7 +71,7 @@
*/ */
+ (AFXMLRequestOperation *)XMLParserRequestOperationWithRequest:(NSURLRequest *)urlRequest + (AFXMLRequestOperation *)XMLParserRequestOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser))success success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure; failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser *XMLParse))failure;
#if __MAC_OS_X_VERSION_MIN_REQUIRED #if __MAC_OS_X_VERSION_MIN_REQUIRED
@ -86,7 +86,7 @@
*/ */
+ (AFXMLRequestOperation *)XMLDocumentRequestOperationWithRequest:(NSURLRequest *)urlRequest + (AFXMLRequestOperation *)XMLDocumentRequestOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLDocument *document))success success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLDocument *document))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure; failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLDocument *document))failure;
#endif #endif
@end @end

View file

@ -53,37 +53,26 @@ static dispatch_queue_t xml_request_operation_processing_queue() {
+ (AFXMLRequestOperation *)XMLParserRequestOperationWithRequest:(NSURLRequest *)urlRequest + (AFXMLRequestOperation *)XMLParserRequestOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser))success success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser *XMLParser))failure
{ {
AFXMLRequestOperation *operation = [[[self alloc] initWithRequest:urlRequest] autorelease]; AFXMLRequestOperation *requestOperation = [[[self alloc] initWithRequest:urlRequest] autorelease];
operation.completionBlock = ^ { [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([operation isCancelled]) { if (success) {
return; success(operation.request, operation.response, responseObject);
} }
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (operation.error) { if (failure) {
if (failure) { failure(operation.request, operation.response, error, [(AFXMLRequestOperation *)operation responseXMLParser]);
dispatch_async(dispatch_get_main_queue(), ^(void) {
failure(operation.request, operation.response, operation.error);
});
}
} else {
NSXMLParser *XMLParser = operation.responseXMLParser;
if (success) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
success(operation.request, operation.response, XMLParser);
});
}
} }
}; }];
return operation; return requestOperation;
} }
#if __MAC_OS_X_VERSION_MIN_REQUIRED #if __MAC_OS_X_VERSION_MIN_REQUIRED
+ (AFXMLRequestOperation *)XMLDocumentRequestOperationWithRequest:(NSURLRequest *)urlRequest + (AFXMLRequestOperation *)XMLDocumentRequestOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLDocument *document))success success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLDocument *document))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLDocument *document))failure
{ {
AFXMLRequestOperation *operation = [[[self alloc] initWithRequest:urlRequest] autorelease]; AFXMLRequestOperation *operation = [[[self alloc] initWithRequest:urlRequest] autorelease];
operation.completionBlock = ^ { operation.completionBlock = ^ {
@ -94,7 +83,7 @@ static dispatch_queue_t xml_request_operation_processing_queue() {
if (operation.error) { if (operation.error) {
if (failure) { if (failure) {
dispatch_async(dispatch_get_main_queue(), ^(void) { dispatch_async(dispatch_get_main_queue(), ^(void) {
failure(operation.request, operation.response, operation.error); failure(operation.request, operation.response, operation.error, [(AFXMLRequestOperation *)operation responseXMLDocument]);
}); });
} }
} else { } else {
@ -165,6 +154,14 @@ static dispatch_queue_t xml_request_operation_processing_queue() {
} }
#endif #endif
- (NSError *)error {
if (_XMLError) {
return _XMLError;
} else {
return [super error];
}
}
#pragma mark - NSOperation #pragma mark - NSOperation
- (void)cancel { - (void)cancel {
@ -173,29 +170,36 @@ static dispatch_queue_t xml_request_operation_processing_queue() {
self.responseXMLParser.delegate = nil; self.responseXMLParser.delegate = nil;
} }
#pragma mark - AFHTTPClientOperation
+ (BOOL)canProcessRequest:(NSURLRequest *)request { + (BOOL)canProcessRequest:(NSURLRequest *)request {
return [[self defaultAcceptableContentTypes] containsObject:[request valueForHTTPHeaderField:@"Accept"]] || [[self defaultAcceptablePathExtensions] containsObject:[[request URL] pathExtension]]; return [[self defaultAcceptableContentTypes] containsObject:[request valueForHTTPHeaderField:@"Accept"]] || [[self defaultAcceptablePathExtensions] containsObject:[[request URL] pathExtension]];
} }
+ (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest - (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
success:(void (^)(id object))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
{ {
self.completionBlock = ^ {
if ([self isCancelled]) {
return;
}
if (self.error) {
if (failure) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
failure(self, self.error);
});
}
} else {
#if __MAC_OS_X_VERSION_MIN_REQUIRED #if __MAC_OS_X_VERSION_MIN_REQUIRED
return [self XMLDocumentRequestOperationWithRequest:urlRequest success:^(NSURLRequest __unused *request, NSHTTPURLResponse __unused *response, NSXMLDocument *XMLDocument) { if (success) {
success(XMLDocument); success(self, self.responseXMLDocument);
} failure:^(NSURLRequest __unused *request, NSHTTPURLResponse *response, NSError *error) { }
failure(response, error);
}];
#else #else
return [self XMLParserRequestOperationWithRequest:urlRequest success:^(NSURLRequest __unused *request, NSHTTPURLResponse __unused *response, NSXMLParser *XMLParser) { if (success) {
success(XMLParser); success(self, self.responseXMLParser);
} failure:^(NSURLRequest __unused *request, NSHTTPURLResponse *response, NSError *error) { }
failure(response, error);
}];
#endif #endif
}
};
} }
@end @end

View file

@ -56,17 +56,19 @@
[mutableParameters setValue:[NSString stringWithFormat:@"%1.7f", location.coordinate.longitude] forKey:@"lng"]; [mutableParameters setValue:[NSString stringWithFormat:@"%1.7f", location.coordinate.longitude] forKey:@"lng"];
} }
[[AFGowallaAPIClient sharedClient] getPath:urlString parameters:mutableParameters success:^(id object) { [[AFGowallaAPIClient sharedClient] getPath:urlString parameters:mutableParameters success:^(__unused AFHTTPRequestOperation *operation, id JSON) {
NSMutableArray *mutableRecords = [NSMutableArray array]; NSMutableArray *mutableRecords = [NSMutableArray array];
for (NSDictionary *attributes in [object valueForKeyPath:@"spots"]) { for (NSDictionary *attributes in [JSON valueForKeyPath:@"spots"]) {
Spot *spot = [[Spot alloc] initWithAttributes:attributes]; @autoreleasepool {
[mutableRecords addObject:spot]; Spot *spot = [[Spot alloc] initWithAttributes:attributes];
[mutableRecords addObject:spot];
}
} }
if (block) { if (block) {
block([NSArray arrayWithArray:mutableRecords]); block([NSArray arrayWithArray:mutableRecords]);
} }
} failure:^(NSHTTPURLResponse *response, NSError *error) { } failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) {
if (block) { if (block) {
block([NSArray array]); block([NSArray array]);
} }

View file

@ -64,9 +64,9 @@
[mutableParameters setValue:[NSString stringWithFormat:@"%1.7f", location.coordinate.longitude] forKey:@"lng"]; [mutableParameters setValue:[NSString stringWithFormat:@"%1.7f", location.coordinate.longitude] forKey:@"lng"];
} }
[[AFGowallaAPIClient sharedClient] getPath:urlString parameters:mutableParameters success:^(id object) { [[AFGowallaAPIClient sharedClient] getPath:urlString parameters:mutableParameters success:^(__unused AFHTTPRequestOperation *operation, id JSON) {
NSMutableArray *mutableRecords = [NSMutableArray array]; NSMutableArray *mutableRecords = [NSMutableArray array];
for (NSDictionary *attributes in [object valueForKeyPath:@"spots"]) { for (NSDictionary *attributes in [JSON valueForKeyPath:@"spots"]) {
Spot *spot = [[[Spot alloc] initWithAttributes:attributes] autorelease]; Spot *spot = [[[Spot alloc] initWithAttributes:attributes] autorelease];
[mutableRecords addObject:spot]; [mutableRecords addObject:spot];
} }
@ -74,7 +74,7 @@
if (block) { if (block) {
block([NSArray arrayWithArray:mutableRecords]); block([NSArray arrayWithArray:mutableRecords]);
} }
} failure:^(NSHTTPURLResponse *response, NSError *error) { } failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) {
if (block) { if (block) {
block([NSArray array]); block([NSArray array]);
} }