Adding Property List request operation

Refactoring implementation of AFHTTPRequestOperation and subclasses
This commit is contained in:
Mattt Thompson 2011-10-05 14:14:52 -05:00
parent 94f08de1d5
commit 2c478758a2
6 changed files with 191 additions and 38 deletions

View file

@ -72,6 +72,7 @@
- (void)dealloc { - (void)dealloc {
[_acceptableStatusCodes release]; [_acceptableStatusCodes release];
[_HTTPError release];
[super dealloc]; [super dealloc];
} }

View file

@ -34,25 +34,11 @@ static dispatch_queue_t image_request_operation_processing_queue() {
@interface AFImageRequestOperation () @interface AFImageRequestOperation ()
@property (readwrite, nonatomic, retain) UIImage *responseImage; @property (readwrite, nonatomic, retain) UIImage *responseImage;
+ (UIImage *)imageWithData:(NSData *)data error:(NSError **)error ;
@end @end
@implementation AFImageRequestOperation @implementation AFImageRequestOperation
@synthesize responseImage = _responseImage; @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 + (AFImageRequestOperation *)imageRequestOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(UIImage *image))success success:(void (^)(UIImage *image))success
{ {
@ -84,7 +70,7 @@ static dispatch_queue_t image_request_operation_processing_queue() {
}); });
} }
} else { } else {
UIImage *image = [[self class] imageWithData:operation.responseData error:nil]; UIImage *image = operation.responseImage;
if (imageProcessingBlock) { if (imageProcessingBlock) {
image = imageProcessingBlock(image); image = imageProcessingBlock(image);
@ -125,7 +111,12 @@ static dispatch_queue_t image_request_operation_processing_queue() {
- (UIImage *)responseImage { - (UIImage *)responseImage {
if (!_responseImage && [self isFinished]) { if (!_responseImage && [self isFinished]) {
self.responseImage = [[self class] imageWithData:self.responseData error:nil]; if ([[UIScreen mainScreen] scale] == 2.0) {
CGImageRef imageRef = [[UIImage imageWithData:self.responseData] CGImage];
self.responseImage = [UIImage imageWithCGImage:imageRef scale:2.0 orientation:UIImageOrientationUp];
} else {
self.responseImage = [UIImage imageWithData:self.responseData];
}
} }
return _responseImage; return _responseImage;

View file

@ -37,35 +37,17 @@ static dispatch_queue_t json_request_operation_processing_queue() {
@interface AFJSONRequestOperation () @interface AFJSONRequestOperation ()
@property (readwrite, nonatomic, retain) id responseJSON; @property (readwrite, nonatomic, retain) id responseJSON;
@property (readwrite, nonatomic, retain) NSError *error; @property (readwrite, nonatomic, retain) NSError *error;
+ (id)JSONObjectWithData:(NSData *)data error:(NSError **)error;
@end @end
@implementation AFJSONRequestOperation @implementation AFJSONRequestOperation
@synthesize responseJSON = _responseJSON; @synthesize responseJSON = _responseJSON;
@synthesize error = _JSONError; @synthesize error = _JSONError;
+ (id)JSONObjectWithData:(NSData *)data error:(NSError **)error {
id JSON = nil;
#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_4_3
if ([NSJSONSerialization class]) {
JSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:error];
} else {
JSON = [[JSONDecoder decoder] objectWithData:data error:error];
}
#else
JSON = [[JSONDecoder decoder] objectWithData:data error:error];
#endif
return JSON;
}
+ (AFJSONRequestOperation *)JSONRequestOperationWithRequest:(NSURLRequest *)urlRequest + (AFJSONRequestOperation *)JSONRequestOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, id JSON))success success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, id JSON))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure
{ {
AFJSONRequestOperation *operation = [[[AFJSONRequestOperation alloc] initWithRequest:urlRequest] autorelease]; AFJSONRequestOperation *operation = [[[self alloc] initWithRequest:urlRequest] autorelease];
operation.completionBlock = ^ { operation.completionBlock = ^ {
if ([operation isCancelled]) { if ([operation isCancelled]) {
return; return;
@ -80,13 +62,13 @@ static dispatch_queue_t json_request_operation_processing_queue() {
} else { } else {
dispatch_async(json_request_operation_processing_queue(), ^(void) { dispatch_async(json_request_operation_processing_queue(), ^(void) {
NSError *error = nil; NSError *error = nil;
id JSON = [self JSONObjectWithData:operation.responseData error:&error]; id JSON = operation.responseJSON;
operation.error = error; operation.error = error;
dispatch_async(dispatch_get_main_queue(), ^(void) { dispatch_async(dispatch_get_main_queue(), ^(void) {
if (operation.error) { if (operation.error) {
if (failure) { if (failure) {
failure(operation.request, operation.response, error); failure(operation.request, operation.response, operation.error);
} }
} else { } else {
if (success) { if (success) {
@ -114,13 +96,24 @@ static dispatch_queue_t json_request_operation_processing_queue() {
- (void)dealloc { - (void)dealloc {
[_responseJSON release]; [_responseJSON release];
[_JSONError release];
[super dealloc]; [super dealloc];
} }
- (id)responseJSON { - (id)responseJSON {
if (!_responseJSON && [self isFinished]) { if (!_responseJSON && [self isFinished]) {
NSError *error = nil; NSError *error = nil;
self.responseJSON = [[self class] JSONObjectWithData:self.responseData error:nil];
#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_4_3
if ([NSJSONSerialization class]) {
self.responseJSON = [NSJSONSerialization JSONObjectWithData:self.responseData options:0 error:&error];
} else {
self.responseJSON = [[JSONDecoder decoder] objectWithData:self.responseData error:&error];
}
#else
self.responseJSON = [[JSONDecoder decoder] objectWithData:self.responseData error:&error];
#endif
self.error = error; self.error = error;
} }

View file

@ -0,0 +1,46 @@
// AFPropertyListRequestOperation.h
//
// Copyright (c) 2011 Gowalla (http://gowalla.com/)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
#import "AFHTTPRequestOperation.h"
@interface AFPropertyListRequestOperation : AFHTTPRequestOperation {
@private
id _responsePropertyList;
NSPropertyListFormat _propertyListFormat;
NSPropertyListReadOptions _propertyListReadOptions;
NSError *_propertyListError;
}
@property (readonly, nonatomic, retain) id responsePropertyList;
@property (readonly, nonatomic, assign) NSPropertyListFormat propertyListFormat;
@property (nonatomic, assign) NSPropertyListReadOptions propertyListReadOptions;
/**
*/
+ (AFPropertyListRequestOperation *)propertyListRequestOperationWithRequest:(NSURLRequest *)request
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, id propertyList))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure;
@end

View file

@ -0,0 +1,116 @@
// AFPropertyListRequestOperation.m
//
// Copyright (c) 2011 Gowalla (http://gowalla.com/)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "AFPropertyListRequestOperation.h"
static dispatch_queue_t af_property_list_request_operation_processing_queue;
static dispatch_queue_t property_list_request_operation_processing_queue() {
if (af_property_list_request_operation_processing_queue == NULL) {
af_property_list_request_operation_processing_queue = dispatch_queue_create("com.alamofire.networking.property-list-request.processing", 0);
}
return af_property_list_request_operation_processing_queue;
}
@interface AFPropertyListRequestOperation ()
@property (readwrite, nonatomic, retain) id responsePropertyList;
@property (readwrite, nonatomic, assign) NSPropertyListFormat propertyListFormat;
@property (readwrite, nonatomic, retain) NSError *error;
@end
@implementation AFPropertyListRequestOperation
@synthesize responsePropertyList = _responsePropertyList;
@synthesize propertyListReadOptions = _propertyListReadOptions;
@synthesize propertyListFormat = _propertyListFormat;
@synthesize error = _propertyListError;
+ (AFPropertyListRequestOperation *)propertyListRequestOperationWithRequest:(NSURLRequest *)request
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, id propertyList))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure
{
AFPropertyListRequestOperation *operation = [[[self alloc] initWithRequest:request] autorelease];
operation.completionBlock = ^ {
if ([operation isCancelled]) {
return;
}
if (operation.error) {
if (failure) {
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;
}
- (id)initWithRequest:(NSURLRequest *)urlRequest {
self = [super initWithRequest:urlRequest];
if (!self) {
return nil;
}
self.acceptableContentTypes = [NSSet setWithObjects:@"application/x-plist", @"application/xml", nil];
self.propertyListReadOptions = NSPropertyListImmutable;
self.propertyListFormat = NSPropertyListXMLFormat_v1_0;
return self;
}
- (void)dealloc {
[_responsePropertyList release];
[_propertyListError release];
[super dealloc];
}
- (id)responsePropertyList {
if (!_responsePropertyList && [self isFinished]) {
NSPropertyListFormat format;
NSError *error = nil;
self.responsePropertyList = [NSPropertyListSerialization propertyListWithData:self.responseData options:self.propertyListReadOptions format:&format error:&error];
self.propertyListFormat = format;
self.error = error;
}
return _responsePropertyList;
}
@end

View file

@ -30,6 +30,7 @@
F8E469671395739D00DB05C8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469661395739D00DB05C8 /* Foundation.framework */; }; F8E469671395739D00DB05C8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469661395739D00DB05C8 /* Foundation.framework */; };
F8E469691395739D00DB05C8 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469681395739D00DB05C8 /* CoreGraphics.framework */; }; F8E469691395739D00DB05C8 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469681395739D00DB05C8 /* CoreGraphics.framework */; };
F8E469DF13957DD500DB05C8 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469DE13957DD500DB05C8 /* CoreLocation.framework */; }; F8E469DF13957DD500DB05C8 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469DE13957DD500DB05C8 /* CoreLocation.framework */; };
F8F4B16E143CD1420064C9E6 /* AFPropertyListRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F8F4B16D143CD1410064C9E6 /* AFPropertyListRequestOperation.m */; };
F8FBFA98142AA239001409DB /* AFHTTPClient.m in Sources */ = {isa = PBXBuildFile; fileRef = F8FBFA97142AA238001409DB /* AFHTTPClient.m */; }; F8FBFA98142AA239001409DB /* AFHTTPClient.m in Sources */ = {isa = PBXBuildFile; fileRef = F8FBFA97142AA238001409DB /* AFHTTPClient.m */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -74,6 +75,8 @@
F8E469DE13957DD500DB05C8 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; F8E469DE13957DD500DB05C8 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
F8E469E013957DF100DB05C8 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; F8E469E013957DF100DB05C8 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
F8E469E213957DF700DB05C8 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; F8E469E213957DF700DB05C8 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
F8F4B16C143CD1410064C9E6 /* AFPropertyListRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFPropertyListRequestOperation.h; path = ../AFNetworking/AFPropertyListRequestOperation.h; sourceTree = "<group>"; };
F8F4B16D143CD1410064C9E6 /* AFPropertyListRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFPropertyListRequestOperation.m; path = ../AFNetworking/AFPropertyListRequestOperation.m; sourceTree = "<group>"; };
F8FBFA96142AA237001409DB /* AFHTTPClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFHTTPClient.h; path = ../AFNetworking/AFHTTPClient.h; sourceTree = "<group>"; }; F8FBFA96142AA237001409DB /* AFHTTPClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFHTTPClient.h; path = ../AFNetworking/AFHTTPClient.h; sourceTree = "<group>"; };
F8FBFA97142AA238001409DB /* AFHTTPClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFHTTPClient.m; path = ../AFNetworking/AFHTTPClient.m; sourceTree = "<group>"; }; F8FBFA97142AA238001409DB /* AFHTTPClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFHTTPClient.m; path = ../AFNetworking/AFHTTPClient.m; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -234,6 +237,8 @@
F8FBFA97142AA238001409DB /* AFHTTPClient.m */, F8FBFA97142AA238001409DB /* AFHTTPClient.m */,
F874B5D313E0AA6500B28E3E /* AFImageRequestOperation.h */, F874B5D313E0AA6500B28E3E /* AFImageRequestOperation.h */,
F874B5CB13E0AA6500B28E3E /* AFImageRequestOperation.m */, F874B5CB13E0AA6500B28E3E /* AFImageRequestOperation.m */,
F8F4B16C143CD1410064C9E6 /* AFPropertyListRequestOperation.h */,
F8F4B16D143CD1410064C9E6 /* AFPropertyListRequestOperation.m */,
F874B5D213E0AA6500B28E3E /* AFImageCache.h */, F874B5D213E0AA6500B28E3E /* AFImageCache.h */,
F874B5CA13E0AA6500B28E3E /* AFImageCache.m */, F874B5CA13E0AA6500B28E3E /* AFImageCache.m */,
F874B5D513E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.h */, F874B5D513E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.h */,
@ -341,6 +346,7 @@
F874B5E013E0AA6500B28E3E /* UIImageView+AFNetworking.m in Sources */, F874B5E013E0AA6500B28E3E /* UIImageView+AFNetworking.m in Sources */,
F8FBFA98142AA239001409DB /* AFHTTPClient.m in Sources */, F8FBFA98142AA239001409DB /* AFHTTPClient.m in Sources */,
F86E5529143A28F3002B438C /* AFURLConnectionOperation.m in Sources */, F86E5529143A28F3002B438C /* AFURLConnectionOperation.m in Sources */,
F8F4B16E143CD1420064C9E6 /* AFPropertyListRequestOperation.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };