Approaching a reasonable design for restructuring AFHTTPRequestOperation and subclasses
This commit is contained in:
parent
c0cba6748a
commit
ccdc5f2d9b
10 changed files with 89 additions and 41 deletions
|
|
@ -183,7 +183,7 @@
|
|||
@param success A block object to be executed when the request operation finishes successfully, with a status code in the 2xx range, and with an acceptable content type (e.g. `application/json`). This block has no return value and takes a single argument, which is an object created from the response data of request.
|
||||
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the resonse data as JSON. This block has no return value and takes a single argument, which is the `NSError` object describing the network or parsing error that occurred.
|
||||
*/
|
||||
- (void)enqueueHTTPOperationWithRequest:(NSURLRequest *)request
|
||||
- (void)enqueueHTTPRequestOperationWithRequest:(NSURLRequest *)request
|
||||
success:(void (^)(id object))success
|
||||
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure;
|
||||
|
||||
|
|
@ -322,3 +322,4 @@
|
|||
*/
|
||||
- (void)appendString:(NSString *)string;
|
||||
@end
|
||||
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
|
|||
return request;
|
||||
}
|
||||
|
||||
- (void)enqueueHTTPOperationWithRequest:(NSURLRequest *)urlRequest
|
||||
- (void)enqueueHTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest
|
||||
success:(void (^)(id object))success
|
||||
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
|
||||
{
|
||||
|
|
@ -257,7 +257,7 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
|
|||
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
|
||||
{
|
||||
NSURLRequest *request = [self requestWithMethod:@"GET" path:path parameters:parameters];
|
||||
[self enqueueHTTPOperationWithRequest:request success:success failure:failure];
|
||||
[self enqueueHTTPRequestOperationWithRequest:request success:success failure:failure];
|
||||
}
|
||||
|
||||
- (void)postPath:(NSString *)path
|
||||
|
|
@ -266,7 +266,7 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
|
|||
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
|
||||
{
|
||||
NSURLRequest *request = [self requestWithMethod:@"POST" path:path parameters:parameters];
|
||||
[self enqueueHTTPOperationWithRequest:request success:success failure:failure];
|
||||
[self enqueueHTTPRequestOperationWithRequest:request success:success failure:failure];
|
||||
}
|
||||
|
||||
- (void)putPath:(NSString *)path
|
||||
|
|
@ -275,7 +275,7 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
|
|||
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
|
||||
{
|
||||
NSURLRequest *request = [self requestWithMethod:@"PUT" path:path parameters:parameters];
|
||||
[self enqueueHTTPOperationWithRequest:request success:success failure:failure];
|
||||
[self enqueueHTTPRequestOperationWithRequest:request success:success failure:failure];
|
||||
}
|
||||
|
||||
- (void)deletePath:(NSString *)path
|
||||
|
|
@ -284,7 +284,7 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
|
|||
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
|
||||
{
|
||||
NSURLRequest *request = [self requestWithMethod:@"DELETE" path:path parameters:parameters];
|
||||
[self enqueueHTTPOperationWithRequest:request success:success failure:failure];
|
||||
[self enqueueHTTPRequestOperationWithRequest:request success:success failure:failure];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "AFURLConnectionOperation.h"
|
||||
|
||||
@protocol AFHTTPClientRequestOperation
|
||||
+ (BOOL)canInitWithRequest:(NSURLRequest *)request;
|
||||
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request;
|
||||
@end
|
||||
|
||||
/**
|
||||
`AFHTTPRequestOperation` is an `NSOperation` subclass that implements the `NSURLConnection` delegate methods, and provides a simple block-based interface to asynchronously get the result and context of that operation finishes.
|
||||
|
||||
|
|
@ -58,6 +63,7 @@
|
|||
@private
|
||||
NSIndexSet *_acceptableStatusCodes;
|
||||
NSSet *_acceptableContentTypes;
|
||||
NSError *_HTTPError;
|
||||
}
|
||||
|
||||
@property (readonly, nonatomic, retain) NSHTTPURLResponse *response;
|
||||
|
|
|
|||
|
|
@ -27,10 +27,9 @@
|
|||
@end
|
||||
|
||||
@implementation AFHTTPRequestOperation
|
||||
@dynamic error;
|
||||
@dynamic response;
|
||||
@synthesize acceptableStatusCodes = _acceptableStatusCodes;
|
||||
@synthesize acceptableContentTypes = _acceptableContentTypes;
|
||||
@synthesize error = _HTTPError;
|
||||
|
||||
+ (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest
|
||||
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSData *data))success
|
||||
|
|
@ -51,7 +50,7 @@
|
|||
} else {
|
||||
if (success) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
||||
success(operation.request, operation.response, operation.responseBody);
|
||||
success(operation.request, operation.response, operation.responseData);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -81,7 +80,7 @@
|
|||
}
|
||||
|
||||
- (NSError *)error {
|
||||
if (self.response && ![super error]) {
|
||||
if (self.response) {
|
||||
if (![self hasAcceptableStatusCode]) {
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
|
||||
[userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected status code %@, got %d", nil), self.acceptableStatusCodes, [self.response statusCode]] forKey:NSLocalizedDescriptionKey];
|
||||
|
|
|
|||
|
|
@ -30,7 +30,12 @@
|
|||
@see NSOperation
|
||||
@see AFHTTPRequestOperation
|
||||
*/
|
||||
@interface AFImageRequestOperation : AFHTTPRequestOperation
|
||||
@interface AFImageRequestOperation : AFHTTPRequestOperation {
|
||||
@private
|
||||
UIImage *_responseImage;
|
||||
}
|
||||
|
||||
@property (readonly, nonatomic, retain) UIImage *responseImage;
|
||||
|
||||
/**
|
||||
Creates and returns an `AFImageRequestOperation` object and sets the specified success callback.
|
||||
|
|
|
|||
|
|
@ -32,7 +32,26 @@ static dispatch_queue_t image_request_operation_processing_queue() {
|
|||
return af_image_request_operation_processing_queue;
|
||||
}
|
||||
|
||||
@interface AFImageRequestOperation ()
|
||||
@property (readwrite, nonatomic, retain) UIImage *responseImage;
|
||||
|
||||
+ (UIImage *)imageWithData:(NSData *)data error:(NSError **)error ;
|
||||
@end
|
||||
|
||||
@implementation AFImageRequestOperation
|
||||
@synthesize responseImage = _responseImage;
|
||||
|
||||
+ (UIImage *)imageWithData:(NSData *)data error:(NSError **)__unused error {
|
||||
UIImage *image = nil;
|
||||
if ([[UIScreen mainScreen] scale] == 2.0) {
|
||||
CGImageRef imageRef = [[UIImage imageWithData:data] CGImage];
|
||||
image = [UIImage imageWithCGImage:imageRef scale:2.0 orientation:UIImageOrientationUp];
|
||||
} else {
|
||||
image = [UIImage imageWithData:data];
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
+ (AFImageRequestOperation *)imageRequestOperationWithRequest:(NSURLRequest *)urlRequest
|
||||
success:(void (^)(UIImage *image))success
|
||||
|
|
@ -65,23 +84,18 @@ static dispatch_queue_t image_request_operation_processing_queue() {
|
|||
});
|
||||
}
|
||||
} else {
|
||||
UIImage *image = nil;
|
||||
if ([[UIScreen mainScreen] scale] == 2.0) {
|
||||
CGImageRef imageRef = [[UIImage imageWithData:operation.responseBody] CGImage];
|
||||
image = [UIImage imageWithCGImage:imageRef scale:2.0 orientation:UIImageOrientationUp];
|
||||
} else {
|
||||
image = [UIImage imageWithData:operation.responseBody];
|
||||
}
|
||||
UIImage *image = [[self class] imageWithData:operation.responseData error:nil];
|
||||
|
||||
if (imageProcessingBlock) {
|
||||
image = imageProcessingBlock(image);
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
||||
if (success) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
||||
|
||||
success(operation.request, operation.response, image);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ([operation.request cachePolicy] != NSURLCacheStorageNotAllowed) {
|
||||
[[AFImageCache sharedImageCache] cacheImage:image forURL:[operation.request URL] cacheName:cacheNameOrNil];
|
||||
|
|
@ -104,4 +118,17 @@ static dispatch_queue_t image_request_operation_processing_queue() {
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_responseImage release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (UIImage *)responseImage {
|
||||
if (!_responseImage && [self isFinished]) {
|
||||
self.responseImage = [[self class] imageWithData:self.responseData error:nil];
|
||||
}
|
||||
|
||||
return _responseImage;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -32,11 +32,11 @@
|
|||
@interface AFJSONRequestOperation : AFHTTPRequestOperation {
|
||||
@private
|
||||
id _responseJSON;
|
||||
NSError *_JSONError;
|
||||
}
|
||||
|
||||
@property (readonly, nonatomic, retain) id responseJSON;
|
||||
|
||||
|
||||
///---------------------------------------
|
||||
/// @name Creating JSON Request Operations
|
||||
///---------------------------------------
|
||||
|
|
|
|||
|
|
@ -36,12 +36,14 @@ static dispatch_queue_t json_request_operation_processing_queue() {
|
|||
|
||||
@interface AFJSONRequestOperation ()
|
||||
@property (readwrite, nonatomic, retain) id responseJSON;
|
||||
@property (readwrite, nonatomic, retain) NSError *error;
|
||||
|
||||
+ (id)JSONObjectWithData:(NSData *)data error:(NSError **)error;
|
||||
@end
|
||||
|
||||
@implementation AFJSONRequestOperation
|
||||
@synthesize responseJSON = _responseJSON;
|
||||
@synthesize error = _JSONError;
|
||||
|
||||
+ (id)JSONObjectWithData:(NSData *)data error:(NSError **)error {
|
||||
id JSON = nil;
|
||||
|
|
@ -65,6 +67,10 @@ static dispatch_queue_t json_request_operation_processing_queue() {
|
|||
{
|
||||
AFJSONRequestOperation *operation = [[[AFJSONRequestOperation alloc] initWithRequest:urlRequest] autorelease];
|
||||
operation.completionBlock = ^ {
|
||||
if ([operation isCancelled]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (operation.error) {
|
||||
if (failure) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
||||
|
|
@ -74,10 +80,11 @@ static dispatch_queue_t json_request_operation_processing_queue() {
|
|||
} else {
|
||||
dispatch_async(json_request_operation_processing_queue(), ^(void) {
|
||||
NSError *error = nil;
|
||||
id JSON = [self JSONObjectWithData:operation.responseBody error:&error];
|
||||
id JSON = [self JSONObjectWithData:operation.responseData error:&error];
|
||||
operation.error = error;
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
||||
if (error) {
|
||||
if (operation.error) {
|
||||
if (failure) {
|
||||
failure(operation.request, operation.response, error);
|
||||
}
|
||||
|
|
@ -111,8 +118,10 @@ static dispatch_queue_t json_request_operation_processing_queue() {
|
|||
}
|
||||
|
||||
- (id)responseJSON {
|
||||
if (!_responseJSON && self.response && self.responseBody) {
|
||||
self.responseJSON = [[self class] JSONObjectWithData:self.responseBody error:nil];
|
||||
if (!_responseJSON && [self isFinished]) {
|
||||
NSError *error = nil;
|
||||
self.responseJSON = [[self class] JSONObjectWithData:self.responseData error:nil];
|
||||
self.error = error;
|
||||
}
|
||||
|
||||
return _responseJSON;
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ extern NSString * const AFNetworkingOperationDidFinishNotification;
|
|||
@property (readonly, nonatomic, retain) NSURLResponse *response;
|
||||
@property (readonly, nonatomic, retain) NSError *error;
|
||||
|
||||
@property (readonly, nonatomic, retain) NSData *responseBody;
|
||||
@property (readonly, nonatomic, retain) NSData *responseData;
|
||||
@property (readonly, nonatomic, copy) NSString *responseString;
|
||||
|
||||
@property (nonatomic, retain) NSInputStream *inputStream;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
@property (readwrite, nonatomic, retain) NSURLRequest *request;
|
||||
@property (readwrite, nonatomic, retain) NSURLResponse *response;
|
||||
@property (readwrite, nonatomic, retain) NSError *error;
|
||||
@property (readwrite, nonatomic, retain) NSData *responseBody;
|
||||
@property (readwrite, nonatomic, retain) NSData *responseData;
|
||||
@property (readwrite, nonatomic, copy) NSString *responseString;
|
||||
@property (readwrite, nonatomic, assign) NSInteger totalBytesRead;
|
||||
@property (readwrite, nonatomic, retain) NSMutableData *dataAccumulator;
|
||||
|
|
@ -78,7 +78,7 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
@synthesize request = _request;
|
||||
@synthesize response = _response;
|
||||
@synthesize error = _error;
|
||||
@synthesize responseBody = _responseBody;
|
||||
@synthesize responseData = _responseBody;
|
||||
@synthesize responseString = _responseString;
|
||||
@synthesize totalBytesRead = _totalBytesRead;
|
||||
@synthesize dataAccumulator = _dataAccumulator;
|
||||
|
|
@ -207,8 +207,9 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
return NO;
|
||||
}
|
||||
case AFHTTPOperationFinishedState:
|
||||
default:
|
||||
return NO;
|
||||
default:
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -223,9 +224,9 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
}
|
||||
|
||||
- (NSString *)responseString {
|
||||
if (!_responseString && self.response && self.responseBody) {
|
||||
if (!_responseString && self.response && self.responseData) {
|
||||
NSStringEncoding textEncoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)self.response.textEncodingName));
|
||||
self.responseString = [[[NSString alloc] initWithData:self.responseBody encoding:textEncoding] autorelease];
|
||||
self.responseString = [[[NSString alloc] initWithData:self.responseData encoding:textEncoding] autorelease];
|
||||
}
|
||||
|
||||
return _responseString;
|
||||
|
|
@ -336,7 +337,7 @@ didReceiveResponse:(NSURLResponse *)response
|
|||
if (self.outputStream) {
|
||||
[self.outputStream close];
|
||||
} else {
|
||||
self.responseBody = [NSData dataWithData:self.dataAccumulator];
|
||||
self.responseData = [NSData dataWithData:self.dataAccumulator];
|
||||
[_dataAccumulator release]; _dataAccumulator = nil;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue