From 7fda89e4a2a409fd178ed19c248a6aaabbf0d428 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Thu, 28 Jun 2012 15:51:27 -0700 Subject: [PATCH 01/76] [Issue #379] Fixing AFHTTPRequestOperation +canProcessRequest: --- AFNetworking/AFHTTPRequestOperation.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index bc9b2b7..0e8e909 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -291,7 +291,7 @@ static id AFStaticClassValueImplementation(id self, SEL _cmd) { } + (BOOL)canProcessRequest:(NSURLRequest *)request { - if (![[self class] isEqual:[AFHTTPRequestOperation class]]) { + if ([[self class] isEqual:[AFHTTPRequestOperation class]]) { return YES; } From a8210a93bb4ab13e7cbcb32518f9f0f5f737101a Mon Sep 17 00:00:00 2001 From: Eric Patey Date: Tue, 10 Jul 2012 21:12:54 -0400 Subject: [PATCH 02/76] Fix threading issue with AFNetworkActivityIndicatorManager. Changed updateNetworkActivityIndicatorVisibilityDelayed to use the main run loop rather than the current run loop for its suppression timer. Also, avoided extra dispatch to the main queue when not needed. --- AFNetworking/AFNetworkActivityIndicatorManager.m | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/AFNetworking/AFNetworkActivityIndicatorManager.m b/AFNetworking/AFNetworkActivityIndicatorManager.m index b141323..53e388f 100644 --- a/AFNetworking/AFNetworkActivityIndicatorManager.m +++ b/AFNetworking/AFNetworkActivityIndicatorManager.m @@ -77,8 +77,8 @@ static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25; // Delay hiding of activity indicator for a short interval, to avoid flickering if (![self isNetworkActivityIndicatorVisible]) { [self.activityIndicatorVisibilityTimer invalidate]; - self.activityIndicatorVisibilityTimer = [NSTimer timerWithTimeInterval:kAFNetworkActivityIndicatorInvisibilityDelay target:self selector:@selector(updateNetworkActivityIndicatorVisibility) userInfo:nil repeats:NO]; - [[NSRunLoop currentRunLoop] addTimer:self.activityIndicatorVisibilityTimer forMode:NSRunLoopCommonModes]; + self.activityIndicatorVisibilityTimer = [NSTimer timerWithTimeInterval:kAFNetworkActivityIndicatorInvisibilityDelay target:self selector:@selector(updateNetworkActivityIndicatorVisibilityOnCurrentQueue) userInfo:nil repeats:NO]; + [[NSRunLoop mainRunLoop] addTimer:self.activityIndicatorVisibilityTimer forMode:NSRunLoopCommonModes]; } else { [self updateNetworkActivityIndicatorVisibility]; } @@ -91,10 +91,14 @@ static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25; - (void)updateNetworkActivityIndicatorVisibility { dispatch_async(dispatch_get_main_queue(), ^{ - [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:[self isNetworkActivityIndicatorVisible]]; + [self updateNetworkActivityIndicatorVisibilityOnCurrentQueue]; }); } +- (void)updateNetworkActivityIndicatorVisibilityOnCurrentQueue { + [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:[self isNetworkActivityIndicatorVisible]]; +} + // Not exposed, but used if activityCount is set via KVC. - (NSInteger)activityCount { return _activityCount; From 415ece4dd459de64de7d73c3d7f28212e0f1703b Mon Sep 17 00:00:00 2001 From: Wen-Hao Lue Date: Wed, 11 Jul 2012 01:04:16 -0700 Subject: [PATCH 03/76] Making the assign attribute on properties explicit to suppress warnings on iOS 6 SDK. --- AFNetworking/AFHTTPRequestOperation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AFNetworking/AFHTTPRequestOperation.h b/AFNetworking/AFHTTPRequestOperation.h index 9cab0e5..bda2d17 100644 --- a/AFNetworking/AFHTTPRequestOperation.h +++ b/AFNetworking/AFHTTPRequestOperation.h @@ -85,12 +85,12 @@ extern NSString * AFCreateIncompleteDownloadDirectoryPath(void); /** The callback dispatch queue on success. If `NULL` (default), the main queue is used. */ -@property (nonatomic) dispatch_queue_t successCallbackQueue; +@property (nonatomic, assign) dispatch_queue_t successCallbackQueue; /** The callback dispatch queue on failure. If `NULL` (default), the main queue is used. */ -@property (nonatomic) dispatch_queue_t failureCallbackQueue; +@property (nonatomic, assign) dispatch_queue_t failureCallbackQueue; ///------------------------------------------------------------- /// @name Managing Accceptable HTTP Status Codes & Content Types From c161a420339fa680da53f80d8848165f3859ac04 Mon Sep 17 00:00:00 2001 From: "tomas.a" Date: Thu, 12 Jul 2012 17:48:12 +0200 Subject: [PATCH 04/76] Fix compiler warning in file upload progress example. Changed NSInteger to long long. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9d5fb45..d207d57 100644 --- a/README.md +++ b/README.md @@ -124,8 +124,8 @@ NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:@"POST }]; AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease]; -[operation setUploadProgressBlock:^(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) { - NSLog(@"Sent %d of %d bytes", totalBytesWritten, totalBytesExpectedToWrite); +[operation setUploadProgressBlock:^(NSInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { + NSLog(@"Sent %lld of %lld bytes", totalBytesWritten, totalBytesExpectedToWrite); }]; [operation start]; ``` From b46284860dc38e7e84caf68a9659073e4dec10d3 Mon Sep 17 00:00:00 2001 From: David Keegan Date: Sat, 21 Jul 2012 23:00:53 -0700 Subject: [PATCH 05/76] String formatting changes wanted by Xcode4.5 on Mountain Lion --- AFNetworking/AFHTTPClient.m | 2 +- AFNetworking/AFHTTPRequestOperation.m | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index b116f3c..fd2312b 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -722,7 +722,7 @@ static inline NSString * AFMultipartFormFinalBoundary() { self.request = request; self.stringEncoding = encoding; - self.temporaryFilePath = [AFMultipartTemporaryFileDirectoryPath() stringByAppendingPathComponent:[NSString stringWithFormat:@"%u", [[self.request URL] hash]]]; + self.temporaryFilePath = [AFMultipartTemporaryFileDirectoryPath() stringByAppendingPathComponent:[NSString stringWithFormat:@"%lu", [[self.request URL] hash]]]; self.outputStream = [NSOutputStream outputStreamToFileAtPath:self.temporaryFilePath append:NO]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 0e8e909..a510960 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -77,11 +77,11 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { } if (range.length == 1) { - [string appendFormat:@"%u", range.location]; + [string appendFormat:@"%lu", range.location]; } else { NSUInteger firstIndex = range.location; NSUInteger lastIndex = firstIndex + range.length - 1; - [string appendFormat:@"%u-%u", firstIndex, lastIndex]; + [string appendFormat:@"%lu-%lu", firstIndex, lastIndex]; } range.location = nextIndex; From 69da97c5a89fd41aa52c3ac699ad549161abc158 Mon Sep 17 00:00:00 2001 From: Steven Fisher Date: Mon, 23 Jul 2012 11:05:58 -0700 Subject: [PATCH 06/76] Cast NSInteger to long. Per Apple's Platform Dependencies in String Programming Guide, casting NSInteger to long before using %lu. https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265-SW5 --- AFNetworking/AFHTTPClient.m | 2 +- AFNetworking/AFHTTPRequestOperation.m | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index fd2312b..9cf237b 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -722,7 +722,7 @@ static inline NSString * AFMultipartFormFinalBoundary() { self.request = request; self.stringEncoding = encoding; - self.temporaryFilePath = [AFMultipartTemporaryFileDirectoryPath() stringByAppendingPathComponent:[NSString stringWithFormat:@"%lu", [[self.request URL] hash]]]; + self.temporaryFilePath = [AFMultipartTemporaryFileDirectoryPath() stringByAppendingPathComponent:[NSString stringWithFormat:@"%lu", (long)[[self.request URL] hash]]]; self.outputStream = [NSOutputStream outputStreamToFileAtPath:self.temporaryFilePath append:NO]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index a510960..d6ba4a3 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -77,11 +77,11 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { } if (range.length == 1) { - [string appendFormat:@"%lu", range.location]; + [string appendFormat:@"%lu", (long)range.location]; } else { NSUInteger firstIndex = range.location; NSUInteger lastIndex = firstIndex + range.length - 1; - [string appendFormat:@"%lu-%lu", firstIndex, lastIndex]; + [string appendFormat:@"%lu-%lu", (long)firstIndex, (long)lastIndex]; } range.location = nextIndex; From 25186f8ebf9cbfd4ec8f32a2a6cca79c7105912f Mon Sep 17 00:00:00 2001 From: Steven Fisher Date: Mon, 23 Jul 2012 11:11:29 -0700 Subject: [PATCH 07/76] Very minor security fix. `informativeTextWithFormat` interprets its string as a format. `[error localizedDescription]` could contain string formatting specifiers. Fixes to use @"%@", [error localizedDescription] instead. Spotted via compiler warning. --- Example/Classes/Models/Tweet.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example/Classes/Models/Tweet.m b/Example/Classes/Models/Tweet.m index 14fe2d0..f9e42f8 100644 --- a/Example/Classes/Models/Tweet.m +++ b/Example/Classes/Models/Tweet.m @@ -67,7 +67,7 @@ #if __IPHONE_OS_VERSION_MIN_REQUIRED [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil) message:[error localizedDescription] delegate:nil cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"OK", nil), nil] show]; #else - [[NSAlert alertWithMessageText:NSLocalizedString(@"Error", nil) defaultButton:NSLocalizedString(@"OK", nil) alternateButton:nil otherButton:nil informativeTextWithFormat:[error localizedDescription]] runModal]; + [[NSAlert alertWithMessageText:NSLocalizedString(@"Error", nil) defaultButton:NSLocalizedString(@"OK", nil) alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@",[error localizedDescription]] runModal]; #endif if (block) { block(nil); From 69ff0781b2e48d052cdfc6ae01747c300b2c7835 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Mon, 23 Jul 2012 12:05:21 -0700 Subject: [PATCH 08/76] Minor refactoring of changes to AFNetworkActivityIndicatorManager Slightly reducing invisibility delay --- AFNetworking/AFNetworkActivityIndicatorManager.m | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/AFNetworking/AFNetworkActivityIndicatorManager.m b/AFNetworking/AFNetworkActivityIndicatorManager.m index 53e388f..5751d16 100644 --- a/AFNetworking/AFNetworkActivityIndicatorManager.m +++ b/AFNetworking/AFNetworkActivityIndicatorManager.m @@ -25,7 +25,7 @@ #import "AFHTTPRequestOperation.h" #if __IPHONE_OS_VERSION_MIN_REQUIRED -static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25; +static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.17; @interface AFNetworkActivityIndicatorManager () @property (readwrite, atomic, assign) NSInteger activityCount; @@ -33,6 +33,7 @@ static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25; @property (readonly, getter = isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible; - (void)updateNetworkActivityIndicatorVisibility; +- (void)updateNetworkActivityIndicatorVisibilityDelayed; @end @implementation AFNetworkActivityIndicatorManager @@ -77,10 +78,10 @@ static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25; // Delay hiding of activity indicator for a short interval, to avoid flickering if (![self isNetworkActivityIndicatorVisible]) { [self.activityIndicatorVisibilityTimer invalidate]; - self.activityIndicatorVisibilityTimer = [NSTimer timerWithTimeInterval:kAFNetworkActivityIndicatorInvisibilityDelay target:self selector:@selector(updateNetworkActivityIndicatorVisibilityOnCurrentQueue) userInfo:nil repeats:NO]; + self.activityIndicatorVisibilityTimer = [NSTimer timerWithTimeInterval:kAFNetworkActivityIndicatorInvisibilityDelay target:self selector:@selector(updateNetworkActivityIndicatorVisibility) userInfo:nil repeats:NO]; [[NSRunLoop mainRunLoop] addTimer:self.activityIndicatorVisibilityTimer forMode:NSRunLoopCommonModes]; } else { - [self updateNetworkActivityIndicatorVisibility]; + [self performSelectorOnMainThread:@selector(updateNetworkActivityIndicatorVisibility) withObject:nil waitUntilDone:NO modes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; } } } @@ -90,12 +91,6 @@ static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25; } - (void)updateNetworkActivityIndicatorVisibility { - dispatch_async(dispatch_get_main_queue(), ^{ - [self updateNetworkActivityIndicatorVisibilityOnCurrentQueue]; - }); -} - -- (void)updateNetworkActivityIndicatorVisibilityOnCurrentQueue { [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:[self isNetworkActivityIndicatorVisible]]; } From 9236e41850c7dbdd50924f6ed25f3d18234fee63 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Mon, 23 Jul 2012 12:15:11 -0700 Subject: [PATCH 09/76] Fixing documentation in AFHTTPClient -deletePath:... to indicate new default of encoding parameters in query string --- AFNetworking/AFHTTPClient.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index 6d11918..043e633 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -423,7 +423,7 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete Creates an `AFHTTPRequestOperation` with a `DELETE` request, and enqueues it to the HTTP client's operation queue. @param path The path to be appended to the HTTP client's base URL and used as the request URL. - @param parameters The parameters to be encoded and set in the request HTTP body. + @param parameters The parameters to be encoded and appended as the query string for the request URL. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the 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. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. From 70787ce4cf4eaa57b175504c031be2e997fbd84a Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Mon, 23 Jul 2012 16:20:11 -0700 Subject: [PATCH 10/76] [Issue #398] Adding state checks to AFURLConnectionOperation -pause to prevent likely memry issues when cancelling a non-existint connection --- AFNetworking/AFURLConnectionOperation.m | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index 9686580..d378465 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -355,15 +355,19 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat } - (void)pause { - if ([self isPaused]) { + if ([self isPaused] || [self isFinished]) { return; } [self.lock lock]; - self.state = AFHTTPOperationPausedState; - [self.connection performSelector:@selector(cancel) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]]; - [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidFinishNotification object:self]; + if ([self isExecuting]) { + [self.connection performSelector:@selector(cancel) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]]; + [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidFinishNotification object:self]; + } + + self.state = AFHTTPOperationPausedState; + [self.lock unlock]; } From b9641edc81f6cb98696c65ae1414a0cf2ca142e3 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Mon, 23 Jul 2012 16:22:48 -0700 Subject: [PATCH 11/76] Updating documentation for -pause Returning early for -pause if operation is already cancelled --- AFNetworking/AFURLConnectionOperation.h | 2 +- AFNetworking/AFURLConnectionOperation.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/AFNetworking/AFURLConnectionOperation.h b/AFNetworking/AFURLConnectionOperation.h index 0da353a..c8c9487 100644 --- a/AFNetworking/AFURLConnectionOperation.h +++ b/AFNetworking/AFURLConnectionOperation.h @@ -159,7 +159,7 @@ extern NSString * const AFNetworkingOperationDidFinishNotification; /** Pauses the execution of the request operation. - @discussion A paused operation returns `NO` for `-isReady`, `-isExecuting`, and `-isFinished`. As such, it will remain in an `NSOperationQueue` until it is either cancelled or resumed. Pausing a finished or cancelled operation has no effect. + @discussion A paused operation returns `NO` for `-isReady`, `-isExecuting`, and `-isFinished`. As such, it will remain in an `NSOperationQueue` until it is either cancelled or resumed. Pausing a finished, cancelled, or paused operation has no effect. */ - (void)pause; diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index d378465..fdacb36 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -355,7 +355,7 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat } - (void)pause { - if ([self isPaused] || [self isFinished]) { + if ([self isPaused] || [self isFinished] || [self isCancelled]) { return; } From 1037a807f5b91387939c538080b787f5ac590a9f Mon Sep 17 00:00:00 2001 From: Steven Fisher Date: Mon, 23 Jul 2012 17:11:54 -0700 Subject: [PATCH 12/76] Fixed warning. containsIndex takes a NSUInteger, not a NSInteger. When CLANG_WARN_IMPLICIT_SIGN_CONVERSION is set, this generates a warning. --- AFNetworking/AFHTTPRequestOperation.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index d6ba4a3..5fca1eb 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -188,7 +188,7 @@ NSString * AFCreateIncompleteDownloadDirectoryPath(void) { } - (BOOL)hasAcceptableStatusCode { - return ![[self class] acceptableStatusCodes] || [[[self class] acceptableStatusCodes] containsIndex:[self.response statusCode]]; + return ![[self class] acceptableStatusCodes] || [[[self class] acceptableStatusCodes] containsIndex:(NSUInteger)[self.response statusCode]]; } - (BOOL)hasAcceptableContentType { From 5c4c94081b864b7d13017496ecbdbd78b761bc67 Mon Sep 17 00:00:00 2001 From: Steven Fisher Date: Mon, 23 Jul 2012 17:19:17 -0700 Subject: [PATCH 13/76] Fixed incomplete implementation warning. sharedProfileImageRequestOperationQueue is declared in interface extension, but only implemented on Mac OS X. This causes an incomplete implementation warning. Added same #if around interface as surrounds impelmentation. This only affects sample code. --- Example/Classes/Models/User.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Example/Classes/Models/User.m b/Example/Classes/Models/User.m index 6f54c7f..c22bae1 100644 --- a/Example/Classes/Models/User.m +++ b/Example/Classes/Models/User.m @@ -26,7 +26,9 @@ NSString * const kUserProfileImageDidLoadNotification = @"com.alamofire.user.profile-image.loaded"; @interface User () +#if __MAC_OS_X_VERSION_MIN_REQUIRED + (NSOperationQueue *)sharedProfileImageRequestOperationQueue; +#endif @end @implementation User { From ee9500ebffc8d16e366714ec54fd2a6e8bb78d77 Mon Sep 17 00:00:00 2001 From: Steven Fisher Date: Mon, 23 Jul 2012 17:26:13 -0700 Subject: [PATCH 14/76] Just spotted a typo in the README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d207d57..cfa7383 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ AFNetworking is architected to be as small and modular as possible, in order to Images AFImageRequestOperation - A subclass of AFHTTPRequestOperation for downloading an processing images. + A subclass of AFHTTPRequestOperation for downloading and processing images. UIImageView+AFNetworking From 8e2da876d90838d1615180440e7fc3efaec0bec9 Mon Sep 17 00:00:00 2001 From: Steven Fisher Date: Mon, 23 Jul 2012 19:26:51 -0700 Subject: [PATCH 15/76] Small README fix Markdown for code syntax does not work in a table cell. Now using . --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cfa7383..5eb48b6 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ AFNetworking is architected to be as small and modular as possible, in order to UIImageView+AFNetworking - Adds methods to `UIImageView` for loading remote images asynchronously from a URL. + Adds methods to UIImageView for loading remote images asynchronously from a URL. From eafbfec11c57fdd67568c17e7b6c6c5fe1fc7a85 Mon Sep 17 00:00:00 2001 From: Steven Fisher Date: Tue, 24 Jul 2012 12:36:25 -0700 Subject: [PATCH 16/76] Fixes warning about using == on floats. If the value changes from near to 2.0 to some other near 2.0, it's fine to recalculate. Thus, use #pragma clang diagnostic to explicitly turn off the float-equal warning. --- AFNetworking/AFImageRequestOperation.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AFNetworking/AFImageRequestOperation.m b/AFNetworking/AFImageRequestOperation.m index beeae69..fbd1e22 100644 --- a/AFNetworking/AFImageRequestOperation.m +++ b/AFNetworking/AFImageRequestOperation.m @@ -161,9 +161,12 @@ static dispatch_queue_t image_request_operation_processing_queue() { } - (void)setImageScale:(CGFloat)imageScale { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wfloat-equal" if (imageScale == _imageScale) { return; } +#pragma clang diagnostic pop _imageScale = imageScale; From 1d82992f36494fc8f0bfcb33b9702f75b1ea6f6c Mon Sep 17 00:00:00 2001 From: Steven Fisher Date: Fri, 3 Aug 2012 19:56:48 -0700 Subject: [PATCH 17/76] Fixed comment Grammar problem in comment. Minor and easy to miss. --- AFNetworking/AFHTTPClient.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index 043e633..089a57e 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -210,7 +210,7 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete @param The subclass of `AFHTTPRequestOperation` to register - @return `YES` if the registration is successful, `NO` otherwise. The only failure condition is if `operationClass` does is not a subclass of `AFHTTPRequestOperation`. + @return `YES` if the registration is successful, `NO` otherwise. The only failure condition is if `operationClass` 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 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. From c9680e1246d9e6184a6495a2803338541215cbb9 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Sat, 4 Aug 2012 15:34:09 -0400 Subject: [PATCH 18/76] [Issue #411] Dispatching upload/download progress blocks to the main queue --- AFNetworking/AFURLConnectionOperation.h | 8 +++++--- AFNetworking/AFURLConnectionOperation.m | 8 ++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/AFNetworking/AFURLConnectionOperation.h b/AFNetworking/AFURLConnectionOperation.h index c8c9487..cc7d93f 100644 --- a/AFNetworking/AFURLConnectionOperation.h +++ b/AFNetworking/AFURLConnectionOperation.h @@ -197,7 +197,9 @@ extern NSString * const AFNetworkingOperationDidFinishNotification; /** Sets a callback to be called when an undetermined number of bytes have been uploaded to the server. - @param block A block object to be called when an undetermined number of bytes have been uploaded to the server. This block has no return value and takes three arguments: the number of bytes written since the last time the upload progress block was called, the total bytes written, and the total bytes expected to be written during the request, as initially determined by the length of the HTTP body. This block may be called multiple times. + @param block A block object to be called when an undetermined number of bytes have been uploaded to the server. This block has no return value and takes three arguments: the number of bytes written since the last time the upload progress block was called, the total bytes written, and the total bytes expected to be written during the request, as initially determined by the length of the HTTP body. This block may be called multiple times, and will execute on the main thread. + + @discussion This block is called on the main thread. @see setDownloadProgressBlock */ @@ -206,8 +208,8 @@ extern NSString * const AFNetworkingOperationDidFinishNotification; /** Sets a callback to be called when an undetermined number of bytes have been downloaded from the server. - @param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times. - + @param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the main thread. + @see setUploadProgressBlock */ - (void)setDownloadProgressBlock:(void (^)(NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block; diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index fdacb36..7defb7f 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -539,7 +539,9 @@ didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { if (self.uploadProgress) { - self.uploadProgress(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); + dispatch_async(dispatch_get_main_queue(), ^{ + self.uploadProgress(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); + }); } } @@ -562,7 +564,9 @@ didReceiveResponse:(NSURLResponse *)response } if (self.downloadProgress) { - self.downloadProgress((long long)[data length], self.totalBytesRead, self.response.expectedContentLength); + dispatch_async(dispatch_get_main_queue(), ^{ + self.downloadProgress((long long)[data length], self.totalBytesRead, self.response.expectedContentLength); + }); } } From b494bfe3fb5281a4a20085420e854189a12cd4bd Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Sat, 4 Aug 2012 15:48:01 -0400 Subject: [PATCH 19/76] Adding NSURLConnection delegate method declarations in the AFURLConnection header to allow subclasses to call out to super implementation. Will be removed in 1.0, since iOS 5 / Mac OS 10.7 defined these as a formal protocol. --- AFNetworking/AFURLConnectionOperation.h | 34 +++++++++++++++++++++++++ AFNetworking/AFURLConnectionOperation.m | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/AFNetworking/AFURLConnectionOperation.h b/AFNetworking/AFURLConnectionOperation.h index cc7d93f..1aca1d1 100644 --- a/AFNetworking/AFURLConnectionOperation.h +++ b/AFNetworking/AFURLConnectionOperation.h @@ -251,4 +251,38 @@ extern NSString * const AFNetworkingOperationDidFinishNotification; */ - (void)setCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse))block; +///--------------------------------------- +/// @name NSURLConnection Delegate Methods +/// @discussion NSURLConnection delegate methods were part of an informal protocol until iOS 5 & Mac OS 10.7, so the method signatures are declared here in order to allow subclasses to override these methods and call back to the super implementation. +///--------------------------------------- + +- (BOOL)connection:(NSURLConnection *)connection +canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace; + +- (void)connection:(NSURLConnection *)connection +didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; + +- (NSURLRequest *)connection:(NSURLConnection *)connection + willSendRequest:(NSURLRequest *)request + redirectResponse:(NSURLResponse *)redirectResponse; + +- (void)connection:(NSURLConnection *)connection + didSendBodyData:(NSInteger)bytesWritten + totalBytesWritten:(NSInteger)totalBytesWritten +totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite; + +- (void)connection:(NSURLConnection *)connection +didReceiveResponse:(NSURLResponse *)response; + +- (void)connection:(NSURLConnection *)connection + didReceiveData:(NSData *)data; + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection; + +- (void)connection:(NSURLConnection *)connection + didFailWithError:(NSError *)error; + +- (NSCachedURLResponse *)connection:(NSURLConnection *)connection + willCacheResponse:(NSCachedURLResponse *)cachedResponse; + @end diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index 7defb7f..9d5d95f 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -524,7 +524,7 @@ didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge - (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request - redirectResponse:(NSURLResponse *)redirectResponse; + redirectResponse:(NSURLResponse *)redirectResponse { if (self.redirectResponse) { return self.redirectResponse(connection, request, redirectResponse); From 5cac0fea1be1fba2b9b1ec1ebf65da5b4ed14d1f Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Mon, 6 Aug 2012 17:22:34 -0400 Subject: [PATCH 20/76] Removing leftover methods and functions from download operation patch --- AFNetworking/AFHTTPRequestOperation.h | 26 -------------------- AFNetworking/AFHTTPRequestOperation.m | 34 --------------------------- 2 files changed, 60 deletions(-) diff --git a/AFNetworking/AFHTTPRequestOperation.h b/AFNetworking/AFHTTPRequestOperation.h index bda2d17..891cd0f 100644 --- a/AFNetworking/AFHTTPRequestOperation.h +++ b/AFNetworking/AFHTTPRequestOperation.h @@ -28,8 +28,6 @@ */ extern NSSet * AFContentTypesFromHTTPHeader(NSString *string); -extern NSString * AFCreateIncompleteDownloadDirectoryPath(void); - /** `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. */ @@ -44,30 +42,6 @@ extern NSString * AFCreateIncompleteDownloadDirectoryPath(void); */ @property (readonly, nonatomic, retain) NSHTTPURLResponse *response; -/** - Set a target file for the response, will stream directly into this destination. - Defaults to nil, which will use a memory stream. Will create a new outputStream on change. - - Note: Changing this while the request is not in ready state will be ignored. - */ -@property (nonatomic, copy) NSString *responseFilePath; - - -/** - Expected total length. This is different than expectedContentLength if the file is resumed. - On regular requests, this is equal to self.response.expectedContentLength unless we resume a request. - - Note: this can also be -1 if the file size is not sent (*) - */ -@property (assign, readonly) long long totalContentLength; - -/** - Indicator for the file offset on partial/resumed downloads. - This is greater than zero if the file download is resumed. - */ -@property (assign, readonly) long long offsetContentLength; - - ///---------------------------------------------------------- /// @name Managing And Checking For Acceptable HTTP Responses ///---------------------------------------------------------- diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 5fca1eb..d4ef94e 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -23,8 +23,6 @@ #import "AFHTTPRequestOperation.h" #import -NSString * const kAFNetworkingIncompleteDownloadDirectoryName = @"Incomplete"; - NSSet * AFContentTypesFromHTTPHeader(NSString *string) { static NSCharacterSet *_skippedCharacterSet = nil; static dispatch_once_t onceToken; @@ -91,24 +89,6 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { return string; } -NSString * AFCreateIncompleteDownloadDirectoryPath(void) { - static NSString *incompleteDownloadPath; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSString *tempDirectory = NSTemporaryDirectory(); - incompleteDownloadPath = [[tempDirectory stringByAppendingPathComponent:kAFNetworkingIncompleteDownloadDirectoryName] retain]; - - NSError *error = nil; - NSFileManager *fileMan = [[NSFileManager alloc] init]; - if(![fileMan createDirectoryAtPath:incompleteDownloadPath withIntermediateDirectories:YES attributes:nil error:&error]) { - NSLog(@"Failed to create incomplete downloads directory at %@", incompleteDownloadPath); - } - [fileMan release]; - }); - - return incompleteDownloadPath; -} - #pragma mark - @interface AFHTTPRequestOperation () @@ -121,7 +101,6 @@ NSString * AFCreateIncompleteDownloadDirectoryPath(void) { @implementation AFHTTPRequestOperation @synthesize HTTPError = _HTTPError; -@synthesize responseFilePath = _responseFilePath; @synthesize successCallbackQueue = _successCallbackQueue; @synthesize failureCallbackQueue = _failureCallbackQueue; @synthesize totalContentLength = _totalContentLength; @@ -247,19 +226,6 @@ NSString * AFCreateIncompleteDownloadDirectoryPath(void) { }; } -- (void)setResponseFilePath:(NSString *)responseFilePath { - if ([self isReady] && responseFilePath != _responseFilePath) { - [_responseFilePath release]; - _responseFilePath = [responseFilePath retain]; - - if (responseFilePath) { - self.outputStream = [NSOutputStream outputStreamToFileAtPath:responseFilePath append:NO]; - }else { - self.outputStream = [NSOutputStream outputStreamToMemory]; - } - } -} - #pragma mark - AFHTTPRequestOperation static id AFStaticClassValueImplementation(id self, SEL _cmd) { From bff368c096d87351d251faa1867fb36c0721cfbc Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Mon, 6 Aug 2012 17:30:01 -0400 Subject: [PATCH 21/76] Using NSOperationQueueDefaultMaxConcurrentOperationCount rather than previously-specified constant (k=4) --- AFNetworking/AFHTTPClient.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 9cf237b..136f24b 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -63,8 +63,6 @@ typedef id AFNetworkReachabilityRef; typedef void (^AFCompletionBlock)(void); -static NSUInteger const kAFHTTPClientDefaultMaxConcurrentOperationCount = 4; - static NSString * AFBase64EncodedStringFromString(NSString *string) { NSData *data = [NSData dataWithBytes:[string UTF8String] length:[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]]; NSUInteger length = [data length]; @@ -285,7 +283,7 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) { #endif self.operationQueue = [[[NSOperationQueue alloc] init] autorelease]; - [self.operationQueue setMaxConcurrentOperationCount:kAFHTTPClientDefaultMaxConcurrentOperationCount]; + [self.operationQueue setMaxConcurrentOperationCount:NSOperationQueueDefaultMaxConcurrentOperationCount]; return self; } From f849627f9a67b3258fcc7aa3673135e0f55a66fe Mon Sep 17 00:00:00 2001 From: Steven Fisher Date: Wed, 8 Aug 2012 11:07:20 -0700 Subject: [PATCH 22/76] initWithBaseURL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes 446. If the URL passed into initWithBaseURL is a file URL rather than a directory URL we will fix it. Without this fix, if you provide "http://myhost/api" as a baseURL and try to get "path", AFNetworking will get http://myhost/path instead of http://myhost/api/path. With the fix, we'll change http://myhost/api to http://myhost/api/. --- AFNetworking/AFHTTPClient.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 136f24b..d9975b4 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -254,6 +254,9 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) { return nil; } + if ( [[url path] length] > 0 && ![[url absoluteString] hasSuffix: @"/"] ) { + url = [url URLByAppendingPathComponent: @""]; + } self.baseURL = url; self.stringEncoding = NSUTF8StringEncoding; From fbc4ec5dbd086b0aafda6b686abe11b97abbddcb Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Sat, 11 Aug 2012 11:12:02 -0400 Subject: [PATCH 23/76] Adding responseString as NSLocalizedRecoverySuggestionErrorKey in errors for unacceptable content type and status code --- AFNetworking/AFHTTPRequestOperation.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index d4ef94e..23c170e 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -129,12 +129,14 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { if (![self hasAcceptableStatusCode]) { NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected status code in (%@), got %d", nil), AFStringFromIndexSet([[self class] acceptableStatusCodes]), [self.response statusCode]] forKey:NSLocalizedDescriptionKey]; + [userInfo setValue:self.responseString forKey:NSLocalizedRecoverySuggestionErrorKey]; [userInfo setValue:[self.request URL] forKey:NSURLErrorFailingURLErrorKey]; self.HTTPError = [[[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadServerResponse userInfo:userInfo] autorelease]; } else if ([self.responseData length] > 0 && ![self hasAcceptableContentType]) { // Don't invalidate content type if there is no content NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected content type %@, got %@", nil), [[self class] acceptableContentTypes], [self.response MIMEType]] forKey:NSLocalizedDescriptionKey]; + [userInfo setValue:self.responseString forKey:NSLocalizedRecoverySuggestionErrorKey]; [userInfo setValue:[self.request URL] forKey:NSURLErrorFailingURLErrorKey]; self.HTTPError = [[[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo] autorelease]; From 3d6fcc35c9cbb9a4275f3c8b72560a32423b2ffc Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Sat, 11 Aug 2012 11:16:55 -0400 Subject: [PATCH 24/76] Moving error alert logic from models to controllers --- .../project.pbxproj | 2 +- Example/AppDelegate.m | 6 +++++- .../Controllers/PublicTimelineViewController.m | 6 ++++-- Example/Classes/Models/Tweet.h | 2 +- Example/Classes/Models/Tweet.m | 13 ++++--------- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Example/AFNetworking iOS Example.xcodeproj/project.pbxproj b/Example/AFNetworking iOS Example.xcodeproj/project.pbxproj index 7abdbab..96e4c23 100644 --- a/Example/AFNetworking iOS Example.xcodeproj/project.pbxproj +++ b/Example/AFNetworking iOS Example.xcodeproj/project.pbxproj @@ -189,8 +189,8 @@ children = ( F8DA09E31396AC040057D0CC /* main.m */, F8129C3815910830009BFE23 /* Prefix.pch */, - F8129C7215910C37009BFE23 /* AppDelegate.m */, F8129C7315910C37009BFE23 /* AppDelegate.h */, + F8129C7215910C37009BFE23 /* AppDelegate.m */, F8E4696C1395739D00DB05C8 /* iOS-Info.plist */, ); name = "Supporting Files"; diff --git a/Example/AppDelegate.m b/Example/AppDelegate.m index 2e27051..fc2ee78 100644 --- a/Example/AppDelegate.m +++ b/Example/AppDelegate.m @@ -71,7 +71,11 @@ didFinishLaunchingWithOptions:(NSDictionary *)launchOptions [self.window makeKeyAndOrderFront:self]; - [Tweet publicTimelineTweetsWithBlock:^(NSArray *tweets) { + [Tweet publicTimelineTweetsWithBlock:^(NSArray *tweets, NSError *error) { + if (error) { + [[NSAlert alertWithMessageText:NSLocalizedString(@"Error", nil) defaultButton:NSLocalizedString(@"OK", nil) alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@",[error localizedDescription]] runModal]; + } + self.tweetsArrayController.content = tweets; }]; diff --git a/Example/Classes/Controllers/PublicTimelineViewController.m b/Example/Classes/Controllers/PublicTimelineViewController.m index 966b607..aad2d63 100644 --- a/Example/Classes/Controllers/PublicTimelineViewController.m +++ b/Example/Classes/Controllers/PublicTimelineViewController.m @@ -41,8 +41,10 @@ [_activityIndicatorView startAnimating]; self.navigationItem.rightBarButtonItem.enabled = NO; - [Tweet publicTimelineTweetsWithBlock:^(NSArray *tweets) { - if (tweets) { + [Tweet publicTimelineTweetsWithBlock:^(NSArray *tweets, NSError *error) { + if (error) { + [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil) message:[error localizedDescription] delegate:nil cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"OK", nil), nil] show]; + } else { _tweets = tweets; [self.tableView reloadData]; } diff --git a/Example/Classes/Models/Tweet.h b/Example/Classes/Models/Tweet.h index a08fd3c..20d9054 100644 --- a/Example/Classes/Models/Tweet.h +++ b/Example/Classes/Models/Tweet.h @@ -33,6 +33,6 @@ - (id)initWithAttributes:(NSDictionary *)attributes; -+ (void)publicTimelineTweetsWithBlock:(void (^)(NSArray *tweets))block; ++ (void)publicTimelineTweetsWithBlock:(void (^)(NSArray *tweets, NSError *error))block; @end diff --git a/Example/Classes/Models/Tweet.m b/Example/Classes/Models/Tweet.m index f9e42f8..d427ae9 100644 --- a/Example/Classes/Models/Tweet.m +++ b/Example/Classes/Models/Tweet.m @@ -52,7 +52,7 @@ #pragma mark - -+ (void)publicTimelineTweetsWithBlock:(void (^)(NSArray *tweets))block { ++ (void)publicTimelineTweetsWithBlock:(void (^)(NSArray *tweets, NSError *error))block { [[AFTwitterAPIClient sharedClient] getPath:@"statuses/public_timeline.json" parameters:[NSDictionary dictionaryWithObject:@"false" forKey:@"include_entities"] success:^(AFHTTPRequestOperation *operation, id JSON) { NSMutableArray *mutableTweets = [NSMutableArray arrayWithCapacity:[JSON count]]; for (NSDictionary *attributes in JSON) { @@ -61,16 +61,11 @@ } if (block) { - block([NSArray arrayWithArray:mutableTweets]); + block([NSArray arrayWithArray:mutableTweets], nil); } - } failure:^(AFHTTPRequestOperation *operation, NSError *error) { -#if __IPHONE_OS_VERSION_MIN_REQUIRED - [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil) message:[error localizedDescription] delegate:nil cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"OK", nil), nil] show]; -#else - [[NSAlert alertWithMessageText:NSLocalizedString(@"Error", nil) defaultButton:NSLocalizedString(@"OK", nil) alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@",[error localizedDescription]] runModal]; -#endif + } failure:^(AFHTTPRequestOperation *operation, NSError *error) { if (block) { - block(nil); + block([NSArray array], error); } }]; } From 481033ae0c811573e17a4a10c7c0c268e0badddf Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Sat, 11 Aug 2012 14:26:03 -0400 Subject: [PATCH 25/76] Minor code reformatting and inline documentation --- AFNetworking/AFHTTPClient.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index d9975b4..62416dc 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -254,9 +254,11 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) { return nil; } - if ( [[url path] length] > 0 && ![[url absoluteString] hasSuffix: @"/"] ) { - url = [url URLByAppendingPathComponent: @""]; + // Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected + if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) { + url = [url URLByAppendingPathComponent:@""]; } + self.baseURL = url; self.stringEncoding = NSUTF8StringEncoding; From 59ef3550d59e1b18a2094445cb2adb2da695eeb7 Mon Sep 17 00:00:00 2001 From: bratley Lower Date: Sun, 12 Aug 2012 09:52:31 -0500 Subject: [PATCH 26/76] add accept header for set uiimage by url --- AFNetworking/UIImageView+AFNetworking.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AFNetworking/UIImageView+AFNetworking.m b/AFNetworking/UIImageView+AFNetworking.m index ac1f708..617fc28 100644 --- a/AFNetworking/UIImageView+AFNetworking.m +++ b/AFNetworking/UIImageView+AFNetworking.m @@ -89,7 +89,7 @@ static char kAFImageRequestOperationObjectKey; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0]; [request setHTTPShouldHandleCookies:NO]; [request setHTTPShouldUsePipelining:YES]; - + [request addValue:@"image/*" forHTTPHeaderField:@"Accept"]; [self setImageWithURLRequest:request placeholderImage:placeholderImage success:nil failure:nil]; } From 782862bd6f948a58d813194aabf45e01cec5652c Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Sun, 12 Aug 2012 19:08:58 -0400 Subject: [PATCH 27/76] [Issue #449] Fixing bug where tempfiles for multipart form message bodies could collide, specifically for requests with the same URL --- AFNetworking/AFHTTPClient.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 62416dc..03a9e5f 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -725,7 +725,7 @@ static inline NSString * AFMultipartFormFinalBoundary() { self.request = request; self.stringEncoding = encoding; - self.temporaryFilePath = [AFMultipartTemporaryFileDirectoryPath() stringByAppendingPathComponent:[NSString stringWithFormat:@"%lu", (long)[[self.request URL] hash]]]; + self.temporaryFilePath = [AFMultipartTemporaryFileDirectoryPath() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]; self.outputStream = [NSOutputStream outputStreamToFileAtPath:self.temporaryFilePath append:NO]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; From b3d63b58c0ecf168682287b583cd81eb23174ce2 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Mon, 13 Aug 2012 13:19:51 -0700 Subject: [PATCH 28/76] Use requestWithURL: instead of requestWithURL:cachePolicy:timeout: in UIImageView category to use default cache policy and timeout --- AFNetworking/UIImageView+AFNetworking.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AFNetworking/UIImageView+AFNetworking.m b/AFNetworking/UIImageView+AFNetworking.m index 617fc28..6de959f 100644 --- a/AFNetworking/UIImageView+AFNetworking.m +++ b/AFNetworking/UIImageView+AFNetworking.m @@ -86,10 +86,11 @@ static char kAFImageRequestOperationObjectKey; - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholderImage { - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPShouldHandleCookies:NO]; [request setHTTPShouldUsePipelining:YES]; [request addValue:@"image/*" forHTTPHeaderField:@"Accept"]; + [self setImageWithURLRequest:request placeholderImage:placeholderImage success:nil failure:nil]; } From 9ed38fd30a7e8d576f131a31154ce60729c22de5 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 15 Aug 2012 08:16:42 -0700 Subject: [PATCH 29/76] Initial implementation of NSCoding and NSCopying support --- AFNetworking/AFURLConnectionOperation.h | 2 +- AFNetworking/AFURLConnectionOperation.m | 61 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/AFNetworking/AFURLConnectionOperation.h b/AFNetworking/AFURLConnectionOperation.h index 1aca1d1..6a17080 100644 --- a/AFNetworking/AFURLConnectionOperation.h +++ b/AFNetworking/AFURLConnectionOperation.h @@ -75,7 +75,7 @@ extern NSString * const AFNetworkingOperationDidFinishNotification; @warning Attempting to load a `file://` URL in iOS 4 may result in an `NSInvalidArgumentException`, caused by the connection returning `NSURLResponse` rather than `NSHTTPURLResponse`, which is the behavior as of iOS 5. */ -@interface AFURLConnectionOperation : NSOperation +@interface AFURLConnectionOperation : NSOperation ///------------------------------- /// @name Accessing Run Loop Modes diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index 9d5d95f..d291fb9 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -606,4 +606,65 @@ didReceiveResponse:(NSURLResponse *)response } } +#pragma mark - NSCoding + +- (id)initWithCoder:(NSCoder *)aDecoder { + NSURLRequest *request = [aDecoder decodeObjectForKey:@"request"]; + + self = [self initWithRequest:request]; + if (!self) { + return nil; + } + + self.runLoopModes = [aDecoder decodeObjectForKey:@"runLoopModes"]; + self.state = [aDecoder decodeIntegerForKey:@"state"]; + self.cancelled = [aDecoder decodeBoolForKey:@"isCancelled"]; + self.response = [aDecoder decodeObjectForKey:@"response"]; + self.error = [aDecoder decodeObjectForKey:@"error"]; + self.responseData = [aDecoder decodeObjectForKey:@"responseData"]; + self.totalBytesRead = [[aDecoder decodeObjectForKey:@"totalBytesRead"] longLongValue]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [self pause]; + + [aCoder encodeObject:self.runLoopModes forKey:@"runLoopModes"]; + [aCoder encodeObject:self.request forKey:@"request"]; + + switch (self.state) { + case AFHTTPOperationExecutingState: + case AFHTTPOperationPausedState: + [aCoder encodeInteger:AFHTTPOperationReadyState forKey:@"state"]; + break; + default: + [aCoder encodeInteger:self.state forKey:@"state"]; + break; + } + + [aCoder encodeBool:[self isCancelled] forKey:@"isCancelled"]; + [aCoder encodeObject:self.response forKey:@"response"]; + [aCoder encodeObject:self.error forKey:@"error"]; + [aCoder encodeObject:self.responseData forKey:@"responseData"]; + [aCoder encodeObject:[NSNumber numberWithLongLong:self.totalBytesRead] forKey:@"totalBytesRead"]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFURLConnectionOperation *operation = [[[self class] allocWithZone:zone] initWithRequest:self.request]; + + operation.runLoopModes = [self.runLoopModes copyWithZone:zone]; + + operation.uploadProgress = [self.uploadProgress copy]; + operation.downloadProgress = [self.downloadProgress copy]; + operation.authenticationAgainstProtectionSpace = [self.authenticationAgainstProtectionSpace copy]; + operation.authenticationChallenge = [self.authenticationChallenge copy]; + operation.cacheResponse = [self.cacheResponse copy]; + operation.redirectResponse = [self.redirectResponse copy]; + + return operation; +} + @end From 248ab6d8b8f125fed49170f323f042851796aa3b Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 15 Aug 2012 08:18:55 -0700 Subject: [PATCH 30/76] Renaming AFOperationState enum values to remove HTTP prefix --- AFNetworking/AFURLConnectionOperation.m | 64 ++++++++++++------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index d291fb9..f70d971 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -26,10 +26,10 @@ #endif typedef enum { - AFHTTPOperationPausedState = -1, - AFHTTPOperationReadyState = 1, - AFHTTPOperationExecutingState = 2, - AFHTTPOperationFinishedState = 3, + AFOperationPausedState = -1, + AFOperationReadyState = 1, + AFOperationExecutingState = 2, + AFOperationFinishedState = 3, } _AFOperationState; typedef signed short AFOperationState; @@ -58,13 +58,13 @@ typedef NSURLRequest * (^AFURLConnectionOperationRedirectResponseBlock)(NSURLCon static inline NSString * AFKeyPathFromOperationState(AFOperationState state) { switch (state) { - case AFHTTPOperationReadyState: + case AFOperationReadyState: return @"isReady"; - case AFHTTPOperationExecutingState: + case AFOperationExecutingState: return @"isExecuting"; - case AFHTTPOperationFinishedState: + case AFOperationFinishedState: return @"isFinished"; - case AFHTTPOperationPausedState: + case AFOperationPausedState: return @"isPaused"; default: return @"state"; @@ -73,28 +73,28 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) { static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperationState toState, BOOL isCancelled) { switch (fromState) { - case AFHTTPOperationReadyState: + case AFOperationReadyState: switch (toState) { - case AFHTTPOperationPausedState: - case AFHTTPOperationExecutingState: + case AFOperationPausedState: + case AFOperationExecutingState: return YES; - case AFHTTPOperationFinishedState: + case AFOperationFinishedState: return isCancelled; default: return NO; } - case AFHTTPOperationExecutingState: + case AFOperationExecutingState: switch (toState) { - case AFHTTPOperationPausedState: - case AFHTTPOperationFinishedState: + case AFOperationPausedState: + case AFOperationFinishedState: return YES; default: return NO; } - case AFHTTPOperationFinishedState: + case AFOperationFinishedState: return NO; - case AFHTTPOperationPausedState: - return toState == AFHTTPOperationReadyState; + case AFOperationPausedState: + return toState == AFOperationReadyState; default: return YES; } @@ -180,7 +180,7 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat self.outputStream = [NSOutputStream outputStreamToMemory]; - self.state = AFHTTPOperationReadyState; + self.state = AFOperationReadyState; return self; } @@ -326,10 +326,10 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat [self didChangeValueForKey:newStateKey]; switch (state) { - case AFHTTPOperationExecutingState: + case AFOperationExecutingState: [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidStartNotification object:self]; break; - case AFHTTPOperationFinishedState: + case AFOperationFinishedState: [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidFinishNotification object:self]; break; default: @@ -366,13 +366,13 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidFinishNotification object:self]; } - self.state = AFHTTPOperationPausedState; + self.state = AFOperationPausedState; [self.lock unlock]; } - (BOOL)isPaused { - return self.state == AFHTTPOperationPausedState; + return self.state == AFOperationPausedState; } - (void)resume { @@ -381,7 +381,7 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat } [self.lock lock]; - self.state = AFHTTPOperationReadyState; + self.state = AFOperationReadyState; [self start]; [self.lock unlock]; @@ -390,15 +390,15 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat #pragma mark - NSOperation - (BOOL)isReady { - return self.state == AFHTTPOperationReadyState && [super isReady]; + return self.state == AFOperationReadyState && [super isReady]; } - (BOOL)isExecuting { - return self.state == AFHTTPOperationExecutingState; + return self.state == AFOperationExecutingState; } - (BOOL)isFinished { - return self.state == AFHTTPOperationFinishedState; + return self.state == AFOperationFinishedState; } - (BOOL)isConcurrent { @@ -408,7 +408,7 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat - (void)start { [self.lock lock]; if ([self isReady]) { - self.state = AFHTTPOperationExecutingState; + self.state = AFOperationExecutingState; [self performSelector:@selector(operationDidStart) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]]; } @@ -434,7 +434,7 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat } - (void)finish { - self.state = AFHTTPOperationFinishedState; + self.state = AFOperationFinishedState; } - (void)cancel { @@ -634,9 +634,9 @@ didReceiveResponse:(NSURLResponse *)response [aCoder encodeObject:self.request forKey:@"request"]; switch (self.state) { - case AFHTTPOperationExecutingState: - case AFHTTPOperationPausedState: - [aCoder encodeInteger:AFHTTPOperationReadyState forKey:@"state"]; + case AFOperationExecutingState: + case AFOperationPausedState: + [aCoder encodeInteger:AFOperationReadyState forKey:@"state"]; break; default: [aCoder encodeInteger:self.state forKey:@"state"]; From 8309f39c40366038e9ef31c30a92591edc32b93d Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 15 Aug 2012 08:19:42 -0700 Subject: [PATCH 31/76] Removing unused kAFHTTPMinimumInitialDataCapacity and kAFHTTPMaximumInitialDataCapacity constants --- AFNetworking/AFURLConnectionOperation.m | 3 --- 1 file changed, 3 deletions(-) diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index f70d971..5ff6182 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -40,9 +40,6 @@ typedef UIBackgroundTaskIdentifier AFBackgroundTaskIdentifier; typedef id AFBackgroundTaskIdentifier; #endif -static NSUInteger const kAFHTTPMinimumInitialDataCapacity = 1024; -static NSUInteger const kAFHTTPMaximumInitialDataCapacity = 1024 * 1024 * 8; - static NSString * const kAFNetworkingLockName = @"com.alamofire.networking.operation.lock"; NSString * const AFNetworkingErrorDomain = @"com.alamofire.networking.error"; From a862d3b596ce6a5fc851b5288047910c1b54ab70 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 15 Aug 2012 08:21:54 -0700 Subject: [PATCH 32/76] Adding method signature for -cancelConnection in AFURLConnectionOperation class extension --- AFNetworking/AFURLConnectionOperation.m | 1 + 1 file changed, 1 insertion(+) diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index 5ff6182..76b6b9f 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -118,6 +118,7 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat - (void)operationDidStart; - (void)finish; +- (void)cancelConnection; @end @implementation AFURLConnectionOperation From 7132b96124f9274dc3ef21aa1ff7bbfe68bf752d Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 15 Aug 2012 09:59:00 -0700 Subject: [PATCH 33/76] Adding documentation for NSCoding / NSCopying behavior Minor fixes to -copyWithZone: Minor refactoring of -encodeWithCoder: --- AFNetworking/AFURLConnectionOperation.h | 14 +++++++++++++ AFNetworking/AFURLConnectionOperation.m | 26 ++++++++++--------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/AFNetworking/AFURLConnectionOperation.h b/AFNetworking/AFURLConnectionOperation.h index 6a17080..b23c6b6 100644 --- a/AFNetworking/AFURLConnectionOperation.h +++ b/AFNetworking/AFURLConnectionOperation.h @@ -73,6 +73,20 @@ extern NSString * const AFNetworkingOperationDidFinishNotification; @warning Subclasses are strongly discouraged from overriding `setCompletionBlock:`, as `AFURLConnectionOperation`'s implementation includes a workaround to mitigate retain cycles, and what Apple rather ominously refers to as "The Deallocation Problem" (See http://developer.apple.com/library/ios/technotes/tn2109/_index.html#//apple_ref/doc/uid/DTS40010274-CH1-SUBSECTION11) + ## NSCoding & NSCopying Conformance + + `AFURLConnectionOperation` conforms to the `NSCoding` and `NSCopying` protocols, allowing operations to be archived to disk, and copied in memory, respectively. However, because of the intrinsic limitations of capturing the exact state of an operation at a particular moment, there are some important caveats to keep in mind: + + ### NSCoding Caveats + + - Encoded operations do not include any block properties. Be sure to set `completionBlock` and any other callback blocks as necessary when using `-initWithCoder:` or `NSKeyedUnarchiver`, for example. + - Operations are paused on `encodeWithCoder:`. If the operation was encoded while paused or still executing, its archived state will return `YES` for `isReady`. Otherwise, the state of an operation when encoding will remain unchanged. + + ### NSCopying Caveats + + - `-copy` and `-copyWithZone:` return a new operation with the `NSURLRequest` of the original. So rather than an exact copy of the operation at that particular instant, the copying mechanism returns a completely new instance, which can be useful for retrying operations. + - Operation copies do not include `completionBlock`, but do include any other callback blocks of the original. `completionBlock` often strongly captures a reference to `self`, which, perhaps surprisingly, would otherwise point to the _original_ operation when copied. + @warning Attempting to load a `file://` URL in iOS 4 may result in an `NSInvalidArgumentException`, caused by the connection returning `NSURLResponse` rather than `NSHTTPURLResponse`, which is the behavior as of iOS 5. */ @interface AFURLConnectionOperation : NSOperation diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index 76b6b9f..d66af7a 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -608,13 +608,10 @@ didReceiveResponse:(NSURLResponse *)response - (id)initWithCoder:(NSCoder *)aDecoder { NSURLRequest *request = [aDecoder decodeObjectForKey:@"request"]; - - self = [self initWithRequest:request]; - if (!self) { + if (!request || ![self initWithRequest:request]) { return nil; } - - self.runLoopModes = [aDecoder decodeObjectForKey:@"runLoopModes"]; + self.state = [aDecoder decodeIntegerForKey:@"state"]; self.cancelled = [aDecoder decodeBoolForKey:@"isCancelled"]; self.response = [aDecoder decodeObjectForKey:@"response"]; @@ -628,7 +625,6 @@ didReceiveResponse:(NSURLResponse *)response - (void)encodeWithCoder:(NSCoder *)aCoder { [self pause]; - [aCoder encodeObject:self.runLoopModes forKey:@"runLoopModes"]; [aCoder encodeObject:self.request forKey:@"request"]; switch (self.state) { @@ -652,16 +648,14 @@ didReceiveResponse:(NSURLResponse *)response - (id)copyWithZone:(NSZone *)zone { AFURLConnectionOperation *operation = [[[self class] allocWithZone:zone] initWithRequest:self.request]; - - operation.runLoopModes = [self.runLoopModes copyWithZone:zone]; - - operation.uploadProgress = [self.uploadProgress copy]; - operation.downloadProgress = [self.downloadProgress copy]; - operation.authenticationAgainstProtectionSpace = [self.authenticationAgainstProtectionSpace copy]; - operation.authenticationChallenge = [self.authenticationChallenge copy]; - operation.cacheResponse = [self.cacheResponse copy]; - operation.redirectResponse = [self.redirectResponse copy]; - + + operation.uploadProgress = self.uploadProgress; + operation.downloadProgress = self.downloadProgress; + operation.authenticationAgainstProtectionSpace = self.authenticationAgainstProtectionSpace; + operation.authenticationChallenge = self.authenticationChallenge; + operation.cacheResponse = self.cacheResponse; + operation.redirectResponse = self.redirectResponse; + return operation; } From 19a491b45bd2265d5614e11fde4f5a77a213493c Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 15 Aug 2012 10:03:46 -0700 Subject: [PATCH 34/76] Adding additional details in NSCopying / NSCopying documentation about stream properties --- AFNetworking/AFURLConnectionOperation.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/AFNetworking/AFURLConnectionOperation.h b/AFNetworking/AFURLConnectionOperation.h index b23c6b6..ace5a86 100644 --- a/AFNetworking/AFURLConnectionOperation.h +++ b/AFNetworking/AFURLConnectionOperation.h @@ -79,13 +79,14 @@ extern NSString * const AFNetworkingOperationDidFinishNotification; ### NSCoding Caveats - - Encoded operations do not include any block properties. Be sure to set `completionBlock` and any other callback blocks as necessary when using `-initWithCoder:` or `NSKeyedUnarchiver`, for example. + - Encoded operations do not include any block or stream properties. Be sure to set `completionBlock`, `outputStream`, and any callback blocks as necessary when using `-initWithCoder:` or `NSKeyedUnarchiver`. - Operations are paused on `encodeWithCoder:`. If the operation was encoded while paused or still executing, its archived state will return `YES` for `isReady`. Otherwise, the state of an operation when encoding will remain unchanged. ### NSCopying Caveats - `-copy` and `-copyWithZone:` return a new operation with the `NSURLRequest` of the original. So rather than an exact copy of the operation at that particular instant, the copying mechanism returns a completely new instance, which can be useful for retrying operations. - - Operation copies do not include `completionBlock`, but do include any other callback blocks of the original. `completionBlock` often strongly captures a reference to `self`, which, perhaps surprisingly, would otherwise point to the _original_ operation when copied. + - A copy of an operation will not include the `outputStream` of the original. + - Operation copies do not include `completionBlock`. `completionBlock` often strongly captures a reference to `self`, which, perhaps surprisingly, would otherwise point to the _original_ operation when copied. @warning Attempting to load a `file://` URL in iOS 4 may result in an `NSInvalidArgumentException`, caused by the connection returning `NSURLResponse` rather than `NSHTTPURLResponse`, which is the behavior as of iOS 5. */ From e8c8367e9962be82c656fae5834db06093e9ed25 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 15 Aug 2012 10:21:41 -0700 Subject: [PATCH 35/76] Squashing compiler warnings in AFURLConnectionOperation -initWithCoder --- AFNetworking/AFURLConnectionOperation.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index d66af7a..88f593b 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -608,7 +608,9 @@ didReceiveResponse:(NSURLResponse *)response - (id)initWithCoder:(NSCoder *)aDecoder { NSURLRequest *request = [aDecoder decodeObjectForKey:@"request"]; - if (!request || ![self initWithRequest:request]) { + + self = [self initWithRequest:request]; + if (!self) { return nil; } From c7df7eacd5139592fc4fe71030bf59cd084ebe03 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 15 Aug 2012 10:22:07 -0700 Subject: [PATCH 36/76] Adding NSCoding and NSCopying conformance to AFHTTPClient --- AFNetworking/AFHTTPClient.h | 8 +++++++- AFNetworking/AFHTTPClient.m | 40 +++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index 089a57e..c70df00 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -124,8 +124,14 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete [NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // http://example.com/foo/ [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/ + ## NSCoding / NSCopying Conformance + + `AFHTTPClient` conforms to the `NSCoding` and `NSCopying` protocols, allowing operations to be archived to disk, and copied in memory, respectively. There are a few minor caveats to keep in mind, however: + + - Archives and copies of HTTP clients will be initialized with an empty operation queue. + - NSCoding cannot serialize / deserialize block properties, so an archive of an HTTP client will not include any reachability callback block that may be set. */ -@interface AFHTTPClient : NSObject +@interface AFHTTPClient : NSObject ///--------------------------------------- /// @name Accessing HTTP Client Properties diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 03a9e5f..be6da27 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -664,6 +664,46 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { [self enqueueHTTPRequestOperation:operation]; } +#pragma mark - NSCoding + +- (id)initWithCoder:(NSCoder *)aDecoder { + NSURL *baseURL = [aDecoder decodeObjectForKey:@"baseURL"]; + + self = [self initWithBaseURL:baseURL]; + if (!self) { + return nil; + } + + self.stringEncoding = [aDecoder decodeIntegerForKey:@"stringEncoding"]; + self.parameterEncoding = [aDecoder decodeIntegerForKey:@"parameterEncoding"]; + self.registeredHTTPOperationClassNames = [aDecoder decodeObjectForKey:@"registeredHTTPOperationClassNames"]; + self.defaultHeaders = [aDecoder decodeObjectForKey:@"defaultHeaders"]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.baseURL forKey:@"baseURL"]; + [aCoder encodeInteger:self.stringEncoding forKey:@"stringEncoding"]; + [aCoder encodeInteger:self.parameterEncoding forKey:@"parameterEncoding"]; + [aCoder encodeObject:self.registeredHTTPOperationClassNames forKey:@"registeredHTTPOperationClassNames"]; + [aCoder encodeObject:self.defaultHeaders forKey:@"defaultHeaders"]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFHTTPClient *HTTPClient = [[[self class] allocWithZone:zone] initWithBaseURL:self.baseURL]; + + HTTPClient.stringEncoding = self.stringEncoding; + HTTPClient.parameterEncoding = self.parameterEncoding; + HTTPClient.registeredHTTPOperationClassNames = [[self.registeredHTTPOperationClassNames copyWithZone:zone] autorelease]; + HTTPClient.defaultHeaders = [[self.defaultHeaders copyWithZone:zone] autorelease]; + HTTPClient.networkReachabilityStatusBlock = self.networkReachabilityStatusBlock; + + return HTTPClient; +} + @end #pragma mark - From 84abd71625d229ccf5fbab136e4647db73ca704f Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Thu, 16 Aug 2012 07:49:50 -0700 Subject: [PATCH 37/76] Issue #463 Adding #ifdef around AFHTTPClient copyWithZone: use of network reachability status block --- AFNetworking/AFHTTPClient.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index be6da27..5602822 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -699,8 +699,9 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { HTTPClient.parameterEncoding = self.parameterEncoding; HTTPClient.registeredHTTPOperationClassNames = [[self.registeredHTTPOperationClassNames copyWithZone:zone] autorelease]; HTTPClient.defaultHeaders = [[self.defaultHeaders copyWithZone:zone] autorelease]; +#ifdef _SYSTEMCONFIGURATION_H HTTPClient.networkReachabilityStatusBlock = self.networkReachabilityStatusBlock; - +#endif return HTTPClient; } From 7787f17469bb1edf0e4765e7ac54af7387a39b3b Mon Sep 17 00:00:00 2001 From: Leo Lobato Date: Tue, 21 Aug 2012 16:40:58 +0200 Subject: [PATCH 38/76] Fix for [Issue #237]. Check if statusCode is available on response class. --- AFNetworking/AFHTTPRequestOperation.m | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 23c170e..29f7254 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -127,8 +127,9 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { - (NSError *)error { if (self.response && !self.HTTPError) { if (![self hasAcceptableStatusCode]) { + int statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? [self.response statusCode] : 200; NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; - [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected status code in (%@), got %d", nil), AFStringFromIndexSet([[self class] acceptableStatusCodes]), [self.response statusCode]] forKey:NSLocalizedDescriptionKey]; + [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected status code in (%@), got %d", nil), AFStringFromIndexSet([[self class] acceptableStatusCodes]), statusCode] forKey:NSLocalizedDescriptionKey]; [userInfo setValue:self.responseString forKey:NSLocalizedRecoverySuggestionErrorKey]; [userInfo setValue:[self.request URL] forKey:NSURLErrorFailingURLErrorKey]; @@ -169,7 +170,8 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { } - (BOOL)hasAcceptableStatusCode { - return ![[self class] acceptableStatusCodes] || [[[self class] acceptableStatusCodes] containsIndex:(NSUInteger)[self.response statusCode]]; + int statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? [self.response statusCode] : 200; + return ![[self class] acceptableStatusCodes] || [[[self class] acceptableStatusCodes] containsIndex:statusCode]; } - (BOOL)hasAcceptableContentType { @@ -276,7 +278,8 @@ didReceiveResponse:(NSURLResponse *)response // 206 = Partial Content. long long totalContentLength = self.response.expectedContentLength; long long fileOffset = 0; - if ([self.response statusCode] != 206) { + int statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? [self.response statusCode] : 200; + if (statusCode != 206) { if ([self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey]) { [self.outputStream setProperty:[NSNumber numberWithInteger:0] forKey:NSStreamFileCurrentOffsetKey]; } else { From c0ef5c1068d0ec6cc00ecae7c37a60303dae0f63 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Tue, 21 Aug 2012 16:06:39 -0700 Subject: [PATCH 39/76] Replacing NSAutoreleasePool with @autoreleasepool --- AFNetworking/AFURLConnectionOperation.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index 88f593b..ad462a4 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -145,9 +145,9 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat + (void)networkRequestThreadEntryPoint:(id)__unused object { do { - NSAutoreleasePool *runLoopPool = [[NSAutoreleasePool alloc] init]; - [[NSRunLoop currentRunLoop] run]; - [runLoopPool drain]; + @autoreleasepool { + [[NSRunLoop currentRunLoop] run]; + } } while (YES); } From 2d7b2f35d643eb9d5eb10ff59452a37c89f681a7 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 22 Aug 2012 10:09:24 -0700 Subject: [PATCH 40/76] [Issue #460] Removing atomic keyword in activityCount property for AFNetworkActivityIndicatorManager --- AFNetworking/AFNetworkActivityIndicatorManager.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/AFNetworking/AFNetworkActivityIndicatorManager.m b/AFNetworking/AFNetworkActivityIndicatorManager.m index 5751d16..cdfe874 100644 --- a/AFNetworking/AFNetworkActivityIndicatorManager.m +++ b/AFNetworking/AFNetworkActivityIndicatorManager.m @@ -28,7 +28,7 @@ static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.17; @interface AFNetworkActivityIndicatorManager () -@property (readwrite, atomic, assign) NSInteger activityCount; +@property (readwrite, assign) NSInteger activityCount; @property (readwrite, nonatomic, retain) NSTimer *activityIndicatorVisibilityTimer; @property (readonly, getter = isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible; @@ -52,6 +52,10 @@ static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.17; return _sharedManager; } ++ (NSSet *)keyPathsForValuesAffectingIsNetworkActivityIndicatorVisible { + return [NSSet setWithObject:@"activityCount"]; +} + - (id)init { self = [super init]; if (!self) { @@ -124,10 +128,6 @@ static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.17; [self updateNetworkActivityIndicatorVisibilityDelayed]; } -+ (NSSet *)keyPathsForValuesAffectingIsNetworkActivityIndicatorVisible { - return [NSSet setWithObject:@"activityCount"]; -} - @end #endif From 706fbe473d6118db12f0c15258d619d6de2e67bc Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 22 Aug 2012 11:31:49 -0700 Subject: [PATCH 41/76] [Issue #469] Optimizing calculation of finished operations in batch progress callback --- AFNetworking/AFHTTPClient.m | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 5602822..53d598a 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -584,9 +584,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { }); dispatch_release(dispatchGroup); }]; - - NSPredicate *finishedOperationPredicate = [NSPredicate predicateWithFormat:@"isFinished == YES"]; - + for (AFHTTPRequestOperation *operation in operations) { AFCompletionBlock originalCompletionBlock = [[operation.completionBlock copy] autorelease]; operation.completionBlock = ^{ @@ -596,8 +594,15 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { originalCompletionBlock(); } + __block NSUInteger numberOfCompletedOperations = 0; + [operations enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + if ([(NSOperation *)obj isFinished]) { + numberOfCompletedOperations++; + } + }]; + if (progressBlock) { - progressBlock([[operations filteredArrayUsingPredicate:finishedOperationPredicate] count], [operations count]); + progressBlock(numberOfCompletedOperations, [operations count]); } dispatch_group_leave(dispatchGroup); From 72a85e1ee69f1c19c7b81d3db35edea8dbed6334 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 22 Aug 2012 11:32:59 -0700 Subject: [PATCH 42/76] Renaming numberOfCompletedOperations variable in progress block to numberOfFinishedOperations --- AFNetworking/AFHTTPClient.h | 4 ++-- AFNetworking/AFHTTPClient.m | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index c70df00..879f727 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -362,7 +362,7 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete @discussion Operations are created by passing the specified `NSURLRequest` objects in `requests`, using `-HTTPRequestOperationWithRequest:success:failure:`, with `nil` for both the `success` and `failure` parameters. */ - (void)enqueueBatchOfHTTPRequestOperationsWithRequests:(NSArray *)requests - progressBlock:(void (^)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations))progressBlock + progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock completionBlock:(void (^)(NSArray *operations))completionBlock; /** @@ -373,7 +373,7 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete @param completionBlock A block object to be executed upon the completion of all of the request operations in the batch. This block has no return value and takes a single argument: the batched request operations. */ - (void)enqueueBatchOfHTTPRequestOperations:(NSArray *)operations - progressBlock:(void (^)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations))progressBlock + progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock completionBlock:(void (^)(NSArray *operations))completionBlock; ///--------------------------- diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 53d598a..53d90ef 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -559,7 +559,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { } - (void)enqueueBatchOfHTTPRequestOperationsWithRequests:(NSArray *)requests - progressBlock:(void (^)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations))progressBlock + progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock completionBlock:(void (^)(NSArray *operations))completionBlock { NSMutableArray *mutableOperations = [NSMutableArray array]; @@ -572,7 +572,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { } - (void)enqueueBatchOfHTTPRequestOperations:(NSArray *)operations - progressBlock:(void (^)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations))progressBlock + progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock completionBlock:(void (^)(NSArray *operations))completionBlock { __block dispatch_group_t dispatchGroup = dispatch_group_create(); @@ -594,15 +594,15 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { originalCompletionBlock(); } - __block NSUInteger numberOfCompletedOperations = 0; + __block NSUInteger numberOfFinishedOperations = 0; [operations enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if ([(NSOperation *)obj isFinished]) { - numberOfCompletedOperations++; + numberOfFinishedOperations++; } }]; if (progressBlock) { - progressBlock(numberOfCompletedOperations, [operations count]); + progressBlock(numberOfFinishedOperations, [operations count]); } dispatch_group_leave(dispatchGroup); From 384df960acdf8e24fcd5bd0981f51452e4d2f5ec Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 22 Aug 2012 11:46:03 -0700 Subject: [PATCH 43/76] Converting int to NSUInteger for instances of manually checking status code in AFHTTPRequestOperation --- AFNetworking/AFHTTPRequestOperation.m | 8 ++++---- AFNetworking/AFURLConnectionOperation.h | 4 +--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 29f7254..a26984b 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -127,7 +127,7 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { - (NSError *)error { if (self.response && !self.HTTPError) { if (![self hasAcceptableStatusCode]) { - int statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? [self.response statusCode] : 200; + NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 200; NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected status code in (%@), got %d", nil), AFStringFromIndexSet([[self class] acceptableStatusCodes]), statusCode] forKey:NSLocalizedDescriptionKey]; [userInfo setValue:self.responseString forKey:NSLocalizedRecoverySuggestionErrorKey]; @@ -170,7 +170,7 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { } - (BOOL)hasAcceptableStatusCode { - int statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? [self.response statusCode] : 200; + NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 200; return ![[self class] acceptableStatusCodes] || [[[self class] acceptableStatusCodes] containsIndex:statusCode]; } @@ -278,7 +278,7 @@ didReceiveResponse:(NSURLResponse *)response // 206 = Partial Content. long long totalContentLength = self.response.expectedContentLength; long long fileOffset = 0; - int statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? [self.response statusCode] : 200; + NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 200; if (statusCode != 206) { if ([self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey]) { [self.outputStream setProperty:[NSNumber numberWithInteger:0] forKey:NSStreamFileCurrentOffsetKey]; @@ -287,7 +287,7 @@ didReceiveResponse:(NSURLResponse *)response self.outputStream = [NSOutputStream outputStreamToMemory]; } } - }else { + } else { NSString *contentRange = [self.response.allHeaderFields valueForKey:@"Content-Range"]; if ([contentRange hasPrefix:@"bytes"]) { NSArray *bytes = [contentRange componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" -/"]]; diff --git a/AFNetworking/AFURLConnectionOperation.h b/AFNetworking/AFURLConnectionOperation.h index ace5a86..4fa20ed 100644 --- a/AFNetworking/AFURLConnectionOperation.h +++ b/AFNetworking/AFURLConnectionOperation.h @@ -86,9 +86,7 @@ extern NSString * const AFNetworkingOperationDidFinishNotification; - `-copy` and `-copyWithZone:` return a new operation with the `NSURLRequest` of the original. So rather than an exact copy of the operation at that particular instant, the copying mechanism returns a completely new instance, which can be useful for retrying operations. - A copy of an operation will not include the `outputStream` of the original. - - Operation copies do not include `completionBlock`. `completionBlock` often strongly captures a reference to `self`, which, perhaps surprisingly, would otherwise point to the _original_ operation when copied. - - @warning Attempting to load a `file://` URL in iOS 4 may result in an `NSInvalidArgumentException`, caused by the connection returning `NSURLResponse` rather than `NSHTTPURLResponse`, which is the behavior as of iOS 5. + - Operation copies do not include `completionBlock`. `completionBlock` often strongly captures a reference to `self`, which, perhaps surprisingly, would otherwise point to the _original_ operation when copied. */ @interface AFURLConnectionOperation : NSOperation From d863759f529f60bc937ff137fbdd1010f1d2bb05 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 22 Aug 2012 11:53:19 -0700 Subject: [PATCH 44/76] Reformatting and documenting AFHTTPRequestOperation -connection:didReceiveResponse: --- AFNetworking/AFHTTPRequestOperation.m | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index a26984b..cf10ba8 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -275,11 +275,21 @@ didReceiveResponse:(NSURLResponse *)response { self.response = (NSHTTPURLResponse *)response; - // 206 = Partial Content. + // Set Content-Range header if status code of response is 206 (Partial Content) + // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7 long long totalContentLength = self.response.expectedContentLength; long long fileOffset = 0; NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 200; - if (statusCode != 206) { + if (statusCode == 206) { + NSString *contentRange = [self.response.allHeaderFields valueForKey:@"Content-Range"]; + if ([contentRange hasPrefix:@"bytes"]) { + NSArray *byteRanges = [contentRange componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" -/"]]; + if ([byteRanges count] == 4) { + fileOffset = [[byteRanges objectAtIndex:1] longLongValue]; + totalContentLength = [[byteRanges objectAtIndex:2] longLongValue] ?: -1; // if this is "*", it's converted to 0, but -1 is default. + } + } + } else { if ([self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey]) { [self.outputStream setProperty:[NSNumber numberWithInteger:0] forKey:NSStreamFileCurrentOffsetKey]; } else { @@ -287,19 +297,11 @@ didReceiveResponse:(NSURLResponse *)response self.outputStream = [NSOutputStream outputStreamToMemory]; } } - } else { - NSString *contentRange = [self.response.allHeaderFields valueForKey:@"Content-Range"]; - if ([contentRange hasPrefix:@"bytes"]) { - NSArray *bytes = [contentRange componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" -/"]]; - if ([bytes count] == 4) { - fileOffset = [[bytes objectAtIndex:1] longLongValue]; - totalContentLength = [[bytes objectAtIndex:2] longLongValue] ?: -1; // if this is *, it's converted to 0, but -1 is default. - } - } - } + self.offsetContentLength = MAX(fileOffset, 0); self.totalContentLength = totalContentLength; + [self.outputStream open]; } From 88b52b0f88afd43440ab77cde6397ba1a50138ed Mon Sep 17 00:00:00 2001 From: Matthias Wessendorf Date: Thu, 23 Aug 2012 19:01:30 +0300 Subject: [PATCH 45/76] fixed type( resonse VS response) --- AFNetworking/AFHTTPClient.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index 879f727..2e590ff 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -323,7 +323,7 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete @param request The request object to be loaded asynchronously during execution of the operation. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the 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. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. + @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 response data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. */ - (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success @@ -386,7 +386,7 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete @param path The path to be appended to the HTTP client's base URL and used as the request URL. @param parameters The parameters to be encoded and appended as the query string for the request URL. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the 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. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. + @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 response data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. @see HTTPRequestOperationWithRequest:success:failure */ @@ -401,7 +401,7 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete @param path The path to be appended to the HTTP client's base URL and used as the request URL. @param parameters The parameters to be encoded and set in the request HTTP body. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the 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. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. + @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 response data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. @see HTTPRequestOperationWithRequest:success:failure */ @@ -416,7 +416,7 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete @param path The path to be appended to the HTTP client's base URL and used as the request URL. @param parameters The parameters to be encoded and set in the request HTTP body. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the 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. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. + @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 response data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. @see HTTPRequestOperationWithRequest:success:failure */ @@ -431,7 +431,7 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete @param path The path to be appended to the HTTP client's base URL and used as the request URL. @param parameters The parameters to be encoded and appended as the query string for the request URL. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the 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. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. + @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 response data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. @see HTTPRequestOperationWithRequest:success:failure */ @@ -446,7 +446,7 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete @param path The path to be appended to the HTTP client's base URL and used as the request URL. @param parameters The parameters to be encoded and set in the request HTTP body. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the 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. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. + @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 response data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. @see HTTPRequestOperationWithRequest:success:failure */ From 1136bc5e2f8493cab0db582b336581c18d01e3dc Mon Sep 17 00:00:00 2001 From: Gareth du Plooy Date: Thu, 23 Aug 2012 11:59:54 -0500 Subject: [PATCH 46/76] Calling downloadProgress no longer casting [data length] to (long long) AFURLConnectionOperationProgressBlock specifies "bytes" as an NSInteger. Master was casting [data length] as a long long, resulting in compilation errors if attempting to compile with more strict complication rules. Only the totalBytes and totalBytesExpected are specified as (and correctly called with) long long values. --- AFNetworking/AFURLConnectionOperation.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index ad462a4..e668aa2 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -563,7 +563,7 @@ didReceiveResponse:(NSURLResponse *)response if (self.downloadProgress) { dispatch_async(dispatch_get_main_queue(), ^{ - self.downloadProgress((long long)[data length], self.totalBytesRead, self.response.expectedContentLength); + self.downloadProgress([data length], self.totalBytesRead, self.response.expectedContentLength); }); } } From dd0e659e09d34288bbe73bd80ff3e232a9bf901e Mon Sep 17 00:00:00 2001 From: Steven Fisher Date: Thu, 23 Aug 2012 10:08:12 -0700 Subject: [PATCH 47/76] Spelling corrections. --- AFNetworking/AFHTTPClient.h | 4 ++-- AFNetworking/AFHTTPRequestOperation.h | 12 ++++++------ AFNetworking/AFJSONRequestOperation.h | 2 +- AFNetworking/AFURLConnectionOperation.h | 6 +++--- AFNetworking/AFXMLRequestOperation.h | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index 2e590ff..84d5965 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -114,7 +114,7 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete ## URL Construction Using Relative Paths - Both `requestWithMethod:path:parameters` and `multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:` construct URLs from the path relative to the `baseURL`, using `NSURL +URLWithString:relativeToURL:`. Below are a few examples of how `baseURL` and relative paths interract: + Both `requestWithMethod:path:parameters` and `multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:` construct URLs from the path relative to the `baseURL`, using `NSURL +URLWithString:relativeToURL:`. Below are a few examples of how `baseURL` and relative paths interact: NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"]; [NSURL URLWithString:@"foo" relativeToURL:baseURL]; // http://example.com/v1/foo @@ -138,7 +138,7 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete ///--------------------------------------- /** - The url used as the base for paths specified in methods such as `getPath:parameteres:success:failure` + The url used as the base for paths specified in methods such as `getPath:parameters:success:failure` */ @property (readonly, nonatomic, retain) NSURL *baseURL; diff --git a/AFNetworking/AFHTTPRequestOperation.h b/AFNetworking/AFHTTPRequestOperation.h index 891cd0f..608a6cb 100644 --- a/AFNetworking/AFHTTPRequestOperation.h +++ b/AFNetworking/AFHTTPRequestOperation.h @@ -66,9 +66,9 @@ extern NSSet * AFContentTypesFromHTTPHeader(NSString *string); */ @property (nonatomic, assign) dispatch_queue_t failureCallbackQueue; -///------------------------------------------------------------- -/// @name Managing Accceptable HTTP Status Codes & Content Types -///------------------------------------------------------------- +///------------------------------------------------------------ +/// @name Managing Acceptable HTTP Status Codes & Content Types +///------------------------------------------------------------ /** Returns an `NSIndexSet` object containing the ranges of acceptable HTTP status codes. When non-`nil`, the operation will set the `error` property to an error in `AFErrorDomain`. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html @@ -78,7 +78,7 @@ extern NSSet * AFContentTypesFromHTTPHeader(NSString *string); + (NSIndexSet *)acceptableStatusCodes; /** - Adds status codes to the set of acceptable HTTP status codes returned by `+acceptableStatusCodes` in subsequent calls by this class and its descendents. + Adds status codes to the set of acceptable HTTP status codes returned by `+acceptableStatusCodes` in subsequent calls by this class and its descendants. @param statusCodes The status codes to be added to the set of acceptable HTTP status codes */ @@ -92,7 +92,7 @@ extern NSSet * AFContentTypesFromHTTPHeader(NSString *string); + (NSSet *)acceptableContentTypes; /** - Adds content types to the set of acceptable MIME types returned by `+acceptableContentTypes` in subsequent calls by this class and its descendents. + Adds content types to the set of acceptable MIME types returned by `+acceptableContentTypes` in subsequent calls by this class and its descendants. @param contentTypes The content types to be added to the set of acceptable MIME types */ @@ -118,7 +118,7 @@ extern NSSet * AFContentTypesFromHTTPHeader(NSString *string); Sets the `completionBlock` property with a block that executes either the specified success or failure block, depending on the state of the request on completion. If `error` returns a value, which can be caused by an unacceptable status code or content type, then `failure` is executed. Otherwise, `success` is executed. @param success The block to be executed on the completion of a successful request. This block has no return value and takes two arguments: the receiver operation and the object constructed from the response data of the request. - @param failure The block to be executed on the completion of an unsuccessful request. This block has no return value and takes two arguments: the receiver operation and the error that occured during the request. + @param failure The block to be executed on the completion of an unsuccessful request. This block has no return value and takes two arguments: the receiver operation and the error that occurred during the request. @discussion This method should be overridden in subclasses in order to specify the response object passed into the success block. */ diff --git a/AFNetworking/AFJSONRequestOperation.h b/AFNetworking/AFJSONRequestOperation.h index a1191f9..84746f2 100644 --- a/AFNetworking/AFJSONRequestOperation.h +++ b/AFNetworking/AFJSONRequestOperation.h @@ -55,7 +55,7 @@ @param urlRequest The request object to be loaded asynchronously during execution of the operation @param success A block object to be executed when the operation finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the JSON object created from the response data of request. - @param failure A block object to be executed when the 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 three arguments: the request sent from the client, the response received from the server, and the error describing the network or parsing error that occurred. + @param failure A block object to be executed when the operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data as JSON. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error describing the network or parsing error that occurred. @return A new JSON request operation */ diff --git a/AFNetworking/AFURLConnectionOperation.h b/AFNetworking/AFURLConnectionOperation.h index 4fa20ed..ab08518 100644 --- a/AFNetworking/AFURLConnectionOperation.h +++ b/AFNetworking/AFURLConnectionOperation.h @@ -23,7 +23,7 @@ #import /** - Indicates an error occured in AFNetworking. + Indicates an error occurred in AFNetworking. @discussion Error codes for AFNetworkingErrorDomain correspond to codes in NSURLErrorDomain. */ @@ -61,7 +61,7 @@ extern NSString * const AFNetworkingOperationDidFinishNotification; - `connection:canAuthenticateAgainstProtectionSpace:` - `connection:didReceiveAuthenticationChallenge:` - If any of these methods are overriden in a subclass, they _must_ call the `super` implementation first. + If any of these methods are overridden in a subclass, they _must_ call the `super` implementation first. ## Class Constructors @@ -114,7 +114,7 @@ extern NSString * const AFNetworkingOperationDidFinishNotification; @property (readonly, nonatomic, retain) NSURLResponse *response; /** - The error, if any, that occured in the lifecycle of the request. + The error, if any, that occurred in the lifecycle of the request. */ @property (readonly, nonatomic, retain) NSError *error; diff --git a/AFNetworking/AFXMLRequestOperation.h b/AFNetworking/AFXMLRequestOperation.h index 0beb677..876c127 100644 --- a/AFNetworking/AFXMLRequestOperation.h +++ b/AFNetworking/AFXMLRequestOperation.h @@ -77,7 +77,7 @@ @param urlRequest The request object to be loaded asynchronously during execution of the operation @param success A block object to be executed when the operation finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the XML document created from the response data of request. - @param failure A block object to be executed when the operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the resonse data as XML. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error describing the network or parsing error that occurred. + @param failure A block object to be executed when the operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data as XML. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error describing the network or parsing error that occurred. @return A new XML request operation */ From 13ec70cc8f5bc5acd3d579c60704e7a8638abc24 Mon Sep 17 00:00:00 2001 From: Gareth du Plooy Date: Thu, 23 Aug 2012 13:15:47 -0500 Subject: [PATCH 48/76] AFURLConnectionOperationProgressBlock bytes now NSUinteger This seems to be the most proper data type for this parameter. What gets passed in for uploadProgress is an NSInteger (guaranteed to be positive), and [NSData length], which is an NSUInteger, for downloadProgress. --- AFNetworking/AFURLConnectionOperation.h | 4 ++-- AFNetworking/AFURLConnectionOperation.m | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/AFNetworking/AFURLConnectionOperation.h b/AFNetworking/AFURLConnectionOperation.h index 4fa20ed..127747c 100644 --- a/AFNetworking/AFURLConnectionOperation.h +++ b/AFNetworking/AFURLConnectionOperation.h @@ -216,7 +216,7 @@ extern NSString * const AFNetworkingOperationDidFinishNotification; @see setDownloadProgressBlock */ -- (void)setUploadProgressBlock:(void (^)(NSInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block; +- (void)setUploadProgressBlock:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block; /** Sets a callback to be called when an undetermined number of bytes have been downloaded from the server. @@ -225,7 +225,7 @@ extern NSString * const AFNetworkingOperationDidFinishNotification; @see setUploadProgressBlock */ -- (void)setDownloadProgressBlock:(void (^)(NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block; +- (void)setDownloadProgressBlock:(void (^)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block; ///------------------------------------------------- /// @name Setting NSURLConnection Delegate Callbacks diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index e668aa2..98a0343 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -47,7 +47,7 @@ NSString * const AFNetworkingErrorDomain = @"com.alamofire.networking.error"; NSString * const AFNetworkingOperationDidStartNotification = @"com.alamofire.networking.operation.start"; NSString * const AFNetworkingOperationDidFinishNotification = @"com.alamofire.networking.operation.finish"; -typedef void (^AFURLConnectionOperationProgressBlock)(NSInteger bytes, long long totalBytes, long long totalBytesExpected); +typedef void (^AFURLConnectionOperationProgressBlock)(NSUInteger bytes, long long totalBytes, long long totalBytesExpected); typedef BOOL (^AFURLConnectionOperationAuthenticationAgainstProtectionSpaceBlock)(NSURLConnection *connection, NSURLProtectionSpace *protectionSpace); typedef void (^AFURLConnectionOperationAuthenticationChallengeBlock)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge); typedef NSCachedURLResponse * (^AFURLConnectionOperationCacheResponseBlock)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse); @@ -287,11 +287,11 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat } #endif -- (void)setUploadProgressBlock:(void (^)(NSInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block { +- (void)setUploadProgressBlock:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block { self.uploadProgress = block; } -- (void)setDownloadProgressBlock:(void (^)(NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block { +- (void)setDownloadProgressBlock:(void (^)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block { self.downloadProgress = block; } From 3ac1eb103127fafa9eb04b1cdf6567c8734fff76 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 29 Aug 2012 09:29:47 -0700 Subject: [PATCH 49/76] Using more idiomatic ?: for success/failureCallbackQueue fallbacks --- AFNetworking/AFJSONRequestOperation.m | 6 +++--- AFNetworking/AFPropertyListRequestOperation.m | 6 +++--- AFNetworking/AFXMLRequestOperation.m | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/AFNetworking/AFJSONRequestOperation.m b/AFNetworking/AFJSONRequestOperation.m index bcdcb7f..dc4a542 100644 --- a/AFNetworking/AFJSONRequestOperation.m +++ b/AFNetworking/AFJSONRequestOperation.m @@ -109,7 +109,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(), ^{ + dispatch_async(self.failureCallbackQueue ?: dispatch_get_main_queue(), ^{ failure(self, self.error); }); } @@ -119,13 +119,13 @@ static dispatch_queue_t json_request_operation_processing_queue() { if (self.JSONError) { if (failure) { - dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ + dispatch_async(self.failureCallbackQueue ?: dispatch_get_main_queue(), ^{ failure(self, self.error); }); } } else { if (success) { - dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ + dispatch_async(self.successCallbackQueue ? : dispatch_get_main_queue(), ^{ success(self, JSON); }); } diff --git a/AFNetworking/AFPropertyListRequestOperation.m b/AFNetworking/AFPropertyListRequestOperation.m index ecca1af..f8fa064 100644 --- a/AFNetworking/AFPropertyListRequestOperation.m +++ b/AFNetworking/AFPropertyListRequestOperation.m @@ -118,7 +118,7 @@ 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(), ^{ + dispatch_async(self.failureCallbackQueue ?: dispatch_get_main_queue(), ^{ failure(self, self.error); }); } @@ -128,13 +128,13 @@ static dispatch_queue_t property_list_request_operation_processing_queue() { if (self.propertyListError) { if (failure) { - dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ + dispatch_async(self.failureCallbackQueue ?: dispatch_get_main_queue(), ^{ failure(self, self.error); }); } } else { if (success) { - dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ + dispatch_async(self.successCallbackQueue ?: dispatch_get_main_queue(), ^{ success(self, propertyList); }); } diff --git a/AFNetworking/AFXMLRequestOperation.m b/AFNetworking/AFXMLRequestOperation.m index f40cacb..f71efd8 100644 --- a/AFNetworking/AFXMLRequestOperation.m +++ b/AFNetworking/AFXMLRequestOperation.m @@ -159,13 +159,13 @@ static dispatch_queue_t xml_request_operation_processing_queue() { if (self.error) { if (failure) { - dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ + dispatch_async(self.failureCallbackQueue ?: dispatch_get_main_queue(), ^{ failure(self, self.error); }); } } else { if (success) { - dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ + dispatch_async(self.successCallbackQueue ?: dispatch_get_main_queue(), ^{ success(self, XMLParser); }); } From d7412b7ae0f8654b03d1be673627d4b479ed0dee Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 29 Aug 2012 10:04:16 -0700 Subject: [PATCH 50/76] Adding prefix_header_contents declaration in Podspec Adding missing dot to end of summary Updating Scott Raymond's e-mail address --- AFNetworking.podspec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AFNetworking.podspec b/AFNetworking.podspec index 3e4dda5..904be11 100644 --- a/AFNetworking.podspec +++ b/AFNetworking.podspec @@ -2,11 +2,11 @@ Pod::Spec.new do |s| s.name = 'AFNetworking' s.version = '0.10.0' s.license = 'MIT' - s.summary = 'A delightful iOS and OS X networking framework' + s.summary = 'A delightful iOS and OS X networking framework.' s.homepage = 'https://github.com/AFNetworking/AFNetworking' - s.authors = {'Mattt Thompson' => 'm@mattt.me', 'Scott Raymond' => 'sco@gowalla.com'} + s.authors = {'Mattt Thompson' => 'm@mattt.me', 'Scott Raymond' => 'sco@scottraymond.net'} s.source = { :git => 'https://github.com/AFNetworking/AFNetworking.git', :tag => '0.10.0' } s.source_files = 'AFNetworking' - s.clean_paths = ['iOS Example', 'Mac Example', 'AFNetworking.xcworkspace'] s.framework = 'SystemConfiguration' + s.prefix_header_contents = "#import " end From bb8aee4a4f5dba9f947d9bd11fc48e4ed6d14aa0 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 29 Aug 2012 10:48:41 -0700 Subject: [PATCH 51/76] [Issue #444] Reducing number of legal characters to escape in query string parameters --- AFNetworking/AFHTTPClient.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 53d90ef..144967d 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -93,9 +93,10 @@ static NSString * AFBase64EncodedStringFromString(NSString *string) { } NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { - static NSString * const kAFLegalCharactersToBeEscaped = @"?!@#$^&%*+=,:;'\"`<>()[]{}/\\|~ "; + // Escape characters that are legal in URIs, but have unintentional semantic significance when used in a query string parameter + static NSString * const kAFLegalCharactersToBeEscaped = @":/.?&=;+!@$()~"; - return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, (CFStringRef)kAFLegalCharactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease]; + return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, (CFStringRef)kAFLegalCharactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease]; } #pragma mark - From e1995eae55106a5d61c160cc1f60022555860da2 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 29 Aug 2012 10:49:55 -0700 Subject: [PATCH 52/76] Significant refactoring and renaming of internal query string serialization functions. Query String parameter components are now pairs, comprised of a field and a corresponding value. --- AFNetworking/AFHTTPClient.m | 88 +++++++++++++++---------------------- 1 file changed, 35 insertions(+), 53 deletions(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 144967d..d91288e 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -92,106 +92,88 @@ static NSString * AFBase64EncodedStringFromString(NSString *string) { return [[[NSString alloc] initWithData:mutableData encoding:NSASCIIStringEncoding] autorelease]; } -NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { +NSString * AFPercentEscapedQueryStringPairMemberFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { // Escape characters that are legal in URIs, but have unintentional semantic significance when used in a query string parameter static NSString * const kAFLegalCharactersToBeEscaped = @":/.?&=;+!@$()~"; - - return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, (CFStringRef)kAFLegalCharactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease]; + + return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, (CFStringRef)kAFLegalCharactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease]; } #pragma mark - -@interface AFQueryStringComponent : NSObject { -@private - NSString *_key; - NSString *_value; -} - -@property (readwrite, nonatomic, retain) id key; +@interface AFQueryStringPair : NSObject +@property (readwrite, nonatomic, retain) id field; @property (readwrite, nonatomic, retain) id value; -- (id)initWithKey:(id)key value:(id)value; +- (id)initWithField:(id)field value:(id)value; - (NSString *)URLEncodedStringValueWithEncoding:(NSStringEncoding)stringEncoding; @end -@implementation AFQueryStringComponent -@synthesize key = _key; +@implementation AFQueryStringPair +@synthesize field = _field; @synthesize value = _value; -- (id)initWithKey:(id)key value:(id)value { +- (id)initWithField:(id)field value:(id)value { self = [super init]; if (!self) { return nil; } - self.key = key; + self.field = field; self.value = value; return self; } - (void)dealloc { - [_key release]; + [_field release]; [_value release]; [super dealloc]; } - (NSString *)URLEncodedStringValueWithEncoding:(NSStringEncoding)stringEncoding { - return [NSString stringWithFormat:@"%@=%@", self.key, AFURLEncodedStringFromStringWithEncoding([self.value description], stringEncoding)]; + return [NSString stringWithFormat:@"%@=%@", AFPercentEscapedQueryStringPairMemberFromStringWithEncoding(self.field, stringEncoding), AFPercentEscapedQueryStringPairMemberFromStringWithEncoding([self.value description], stringEncoding)]; } @end #pragma mark - -extern NSArray * AFQueryStringComponentsFromKeyAndValue(NSString *key, id value); -extern NSArray * AFQueryStringComponentsFromKeyAndDictionaryValue(NSString *key, NSDictionary *value); -extern NSArray * AFQueryStringComponentsFromKeyAndArrayValue(NSString *key, NSArray *value); +extern NSArray * AFQueryStringPairsFromDictionary(NSDictionary *dictionary); +extern NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value); NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *parameters, NSStringEncoding stringEncoding) { - NSMutableArray *mutableComponents = [NSMutableArray array]; - for (AFQueryStringComponent *component in AFQueryStringComponentsFromKeyAndValue(nil, parameters)) { - [mutableComponents addObject:[component URLEncodedStringValueWithEncoding:stringEncoding]]; + NSMutableArray *mutablePairs = [NSMutableArray array]; + for (AFQueryStringPair *pair in AFQueryStringPairsFromDictionary(parameters)) { + [mutablePairs addObject:[pair URLEncodedStringValueWithEncoding:stringEncoding]]; } - return [mutableComponents componentsJoinedByString:@"&"]; + return [mutablePairs componentsJoinedByString:@"&"]; } -NSArray * AFQueryStringComponentsFromKeyAndValue(NSString *key, id value) { +NSArray * AFQueryStringPairsFromDictionary(NSDictionary *dictionary) { + return AFQueryStringPairsFromKeyAndValue(nil, dictionary); +} + +NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) { NSMutableArray *mutableQueryStringComponents = [NSMutableArray array]; if([value isKindOfClass:[NSDictionary class]]) { - [mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndDictionaryValue(key, value)]; + [value enumerateKeysAndObjectsUsingBlock:^(id nestedKey, id nestedValue, BOOL *stop) { + [mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue((key ? [NSString stringWithFormat:@"%@[%@]", key, nestedKey] : nestedKey), nestedValue)]; + }]; } else if([value isKindOfClass:[NSArray class]]) { - [mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndArrayValue(key, value)]; + [value enumerateObjectsUsingBlock:^(id nestedValue, NSUInteger idx, BOOL *stop) { + [mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue([NSString stringWithFormat:@"%@[]", key], nestedValue)]; + }]; } else { - [mutableQueryStringComponents addObject:[[[AFQueryStringComponent alloc] initWithKey:key value:value] autorelease]]; + [mutableQueryStringComponents addObject:[[[AFQueryStringPair alloc] initWithField:key value:value] autorelease]]; } return mutableQueryStringComponents; } -NSArray * AFQueryStringComponentsFromKeyAndDictionaryValue(NSString *key, NSDictionary *value){ - NSMutableArray *mutableQueryStringComponents = [NSMutableArray array]; - - [value enumerateKeysAndObjectsUsingBlock:^(id nestedKey, id nestedValue, BOOL *stop) { - [mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndValue((key ? [NSString stringWithFormat:@"%@[%@]", key, nestedKey] : nestedKey), nestedValue)]; - }]; - - return mutableQueryStringComponents; -} - -NSArray * AFQueryStringComponentsFromKeyAndArrayValue(NSString *key, NSArray *value) { - NSMutableArray *mutableQueryStringComponents = [NSMutableArray array]; - - [value enumerateObjectsUsingBlock:^(id nestedValue, NSUInteger idx, BOOL *stop) { - [mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndValue([NSString stringWithFormat:@"%@[]", key], nestedValue)]; - }]; - - return mutableQueryStringComponents; -} - static NSString * AFJSONStringFromParameters(NSDictionary *parameters) { NSError *error = nil; NSData *JSONData = AFJSONEncode(parameters, &error); @@ -497,16 +479,16 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { __block AFMultipartFormData *formData = [[[AFMultipartFormData alloc] initWithURLRequest:request stringEncoding:self.stringEncoding] autorelease]; if (parameters) { - for (AFQueryStringComponent *component in AFQueryStringComponentsFromKeyAndValue(nil, parameters)) { + for (AFQueryStringPair *pair in AFQueryStringPairsFromDictionary(parameters)) { NSData *data = nil; - if ([component.value isKindOfClass:[NSData class]]) { - data = component.value; + if ([pair.value isKindOfClass:[NSData class]]) { + data = pair.value; } else { - data = [[component.value description] dataUsingEncoding:self.stringEncoding]; + data = [[pair.value description] dataUsingEncoding:self.stringEncoding]; } if (data) { - [formData appendPartWithFormData:data name:[component.key description]]; + [formData appendPartWithFormData:data name:[pair.field description]]; } } } From 0aeaa60a23b7ac5e41301bb570982ef5a6ab2722 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 29 Aug 2012 10:55:34 -0700 Subject: [PATCH 53/76] Removing extern declaration for AFURLEncodedStringFromStringWithEncoding function (CFURLCreateStringByAddingPercentEscapes should be used instead) --- AFNetworking/AFHTTPClient.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index 84d5965..296da7a 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -58,18 +58,6 @@ typedef enum { AFPropertyListParameterEncoding, } AFHTTPClientParameterEncoding; -/** - Returns a string, replacing certain characters with the equivalent percent escape sequence based on the specified encoding. - - @param string The string to URL encode - @param encoding The encoding to use for the replacement. If you are uncertain of the correct encoding, you should use UTF-8 (NSUTF8StringEncoding), which is the encoding designated by RFC 3986 as the correct encoding for use in URLs. - - @discussion The characters escaped are all characters that are not legal URL characters (based on RFC 3986), including any whitespace, punctuation, or special characters. - - @return A URL-encoded string. If it does not need to be modified (no percent escape sequences are missing), this function may merely return string argument. - */ -extern NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSStringEncoding encoding); - /** Returns a query string constructed by a set of parameters, using the specified encoding. From 4b26f26c2d58785aebd30425839c8331864ae665 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 29 Aug 2012 10:57:59 -0700 Subject: [PATCH 54/76] Updating documentation for AFQueryStringFromParametersWithEncoding --- AFNetworking/AFHTTPClient.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index 296da7a..e96592b 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -62,14 +62,13 @@ typedef enum { Returns a query string constructed by a set of parameters, using the specified encoding. @param parameters The parameters used to construct the query string - @param encoding The encoding to use in constructing the query string. If you are uncertain of the correct encoding, you should use UTF-8 (NSUTF8StringEncoding), which is the encoding designated by RFC 3986 as the correct encoding for use in URLs. + @param encoding The encoding to use in constructing the query string. If you are uncertain of the correct encoding, you should use UTF-8 (`NSUTF8StringEncoding`), which is the encoding designated by RFC 3986 as the correct encoding for use in URLs. - @discussion Query strings are constructed by collecting each key-value pair, URL-encoding a string representation of the key-value pair, and then joining the components with "&". + @discussion Query strings are constructed by collecting each key-value pair, percent escaping a string representation of the key-value pair, and then joining the pairs with "&". + If a query string pair has a an `NSArray` for its value, each member of the array will be represented in the format `field[]=value1&field[]value2`. Otherwise, the pair will be formatted as "field=value". String representations of both keys and values are derived using the `-description` method. The constructed query string does not include the ? character used to delimit the query component. - If a key-value pair has a an `NSArray` for its value, each member of the array will be represented in the format `key[]=value1&key[]value2`. Otherwise, the key-value pair will be formatted as "key=value". String representations of both keys and values are derived using the `-description` method. The constructed query string does not include the ? character used to delimit the query component. - - @return A URL-encoded query string + @return A percent-escaped query string */ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *parameters, NSStringEncoding encoding); From 730c35926ad926cab80d053c895f3444daa85f23 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 29 Aug 2012 11:57:25 -0700 Subject: [PATCH 55/76] Improving default AFHTTPClient User-Agent strings --- AFNetworking/AFHTTPClient.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index d91288e..2257cb0 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -257,14 +257,14 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) { // Accept-Language HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 NSString *preferredLanguageCodes = [[NSLocale preferredLanguages] componentsJoinedByString:@", "]; [self setDefaultHeader:@"Accept-Language" value:[NSString stringWithFormat:@"%@, en-us;q=0.8", preferredLanguageCodes]]; - + #if __IPHONE_OS_VERSION_MIN_REQUIRED // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43 - [self setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (%@, %@ %@, %@, Scale/%f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey], @"unknown", [[UIDevice currentDevice] systemName], [[UIDevice currentDevice] systemVersion], [[UIDevice currentDevice] model], ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0)]]; + [self setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleIdentifierKey], CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0f)]]; #elif __MAC_OS_X_VERSION_MIN_REQUIRED - [self setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (%@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey], @"unknown"]]; + [self setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (Mac OS %@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]]]; #endif - + #ifdef _SYSTEMCONFIGURATION_H self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown; [self startMonitoringNetworkReachability]; From ed94ddf7b09263fcc7104e936a7ae1d751199fe7 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 29 Aug 2012 12:24:58 -0700 Subject: [PATCH 56/76] [Issue #472] Defining error keys for failing request and response to be included in NSError created in AFHTTPRequestOperation Refactoring AFHTTPRequestOperation error handling code --- AFNetworking/AFHTTPRequestOperation.m | 25 ++++++++++++++----------- AFNetworking/AFURLConnectionOperation.h | 10 ++++++++++ AFNetworking/AFURLConnectionOperation.m | 4 +++- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index cf10ba8..26b0eb0 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -126,21 +126,24 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { - (NSError *)error { if (self.response && !self.HTTPError) { - if (![self hasAcceptableStatusCode]) { - NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 200; + if (![self hasAcceptableStatusCode] || ![self hasAcceptableContentType]) { NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; - [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected status code in (%@), got %d", nil), AFStringFromIndexSet([[self class] acceptableStatusCodes]), statusCode] forKey:NSLocalizedDescriptionKey]; [userInfo setValue:self.responseString forKey:NSLocalizedRecoverySuggestionErrorKey]; [userInfo setValue:[self.request URL] forKey:NSURLErrorFailingURLErrorKey]; + [userInfo setValue:self.request forKey:AFNetworkingOperationFailingURLRequestErrorKey]; + [userInfo setValue:self.response forKey:AFNetworkingOperationFailingURLResponseErrorKey]; - self.HTTPError = [[[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadServerResponse userInfo:userInfo] autorelease]; - } else if ([self.responseData length] > 0 && ![self hasAcceptableContentType]) { // Don't invalidate content type if there is no content - NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; - [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected content type %@, got %@", nil), [[self class] acceptableContentTypes], [self.response MIMEType]] forKey:NSLocalizedDescriptionKey]; - [userInfo setValue:self.responseString forKey:NSLocalizedRecoverySuggestionErrorKey]; - [userInfo setValue:[self.request URL] forKey:NSURLErrorFailingURLErrorKey]; - - self.HTTPError = [[[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo] autorelease]; + if (![self hasAcceptableStatusCode]) { + NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 200; + [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected status code in (%@), got %d", nil), AFStringFromIndexSet([[self class] acceptableStatusCodes]), statusCode] forKey:NSLocalizedDescriptionKey]; + self.HTTPError = [[[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadServerResponse userInfo:userInfo] autorelease]; + } else if (![self hasAcceptableContentType]) { + // Don't invalidate content type if there is no content + if ([self.responseData length] > 0) { + [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected content type %@, got %@", nil), [[self class] acceptableContentTypes], [self.response MIMEType]] forKey:NSLocalizedDescriptionKey]; + self.HTTPError = [[[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo] autorelease]; + } + } } } diff --git a/AFNetworking/AFURLConnectionOperation.h b/AFNetworking/AFURLConnectionOperation.h index 358b57a..ad7ace8 100644 --- a/AFNetworking/AFURLConnectionOperation.h +++ b/AFNetworking/AFURLConnectionOperation.h @@ -29,6 +29,16 @@ */ extern NSString * const AFNetworkingErrorDomain; +/** + The corresponding value is an `NSURLRequest` containing the request of the operation associated with an error. This key is only present in the `AFNetworkingErrorDomain`. + */ +extern NSString * const AFNetworkingOperationFailingURLRequestErrorKey; + +/** + The corresponding value is an `NSURLResponse` containing the response of the operation associated with an error. This key is only present in the `AFNetworkingErrorDomain`. + */ +extern NSString * const AFNetworkingOperationFailingURLResponseErrorKey; + /** Posted when an operation begins executing. */ diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index 98a0343..e1c0a4b 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -42,7 +42,9 @@ typedef id AFBackgroundTaskIdentifier; static NSString * const kAFNetworkingLockName = @"com.alamofire.networking.operation.lock"; -NSString * const AFNetworkingErrorDomain = @"com.alamofire.networking.error"; +NSString * const AFNetworkingErrorDomain = @"AFNetworkingErrorDomain"; +NSString * const AFNetworkingOperationFailingURLRequestErrorKey = @"AFNetworkingOperationFailingURLRequestErrorKey"; +NSString * const AFNetworkingOperationFailingURLResponseErrorKey = @"AFNetworkingOperationFailingURLResponseErrorKey"; NSString * const AFNetworkingOperationDidStartNotification = @"com.alamofire.networking.operation.start"; NSString * const AFNetworkingOperationDidFinishNotification = @"com.alamofire.networking.operation.finish"; From ebe06c227d6deaaa027f51d40650dc7b111b6198 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 29 Aug 2012 12:25:53 -0700 Subject: [PATCH 57/76] Changing error domain for failure to recognize file URL in multipart form data builder --- AFNetworking/AFHTTPClient.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 2257cb0..af82843 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -849,7 +849,7 @@ static inline NSString * AFMultipartFormFinalBoundary() { [userInfo setValue:fileURL forKey:NSURLErrorFailingURLErrorKey]; [userInfo setValue:NSLocalizedString(@"Expected URL to be a file URL", nil) forKey:NSLocalizedFailureReasonErrorKey]; if (error != NULL) { - *error = [[[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadURL userInfo:userInfo] autorelease]; + *error = [[[NSError alloc] initWithDomain:NSURLErrorDomain code:NSURLErrorBadURL userInfo:userInfo] autorelease]; } return NO; From 4f89cc650ec115e9c6c35be856f7563748ff0b96 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 29 Aug 2012 14:15:35 -0700 Subject: [PATCH 58/76] Significant restructuring and editing of documentation, organizing notifications, functions, and constants into separate sections at the end of the class header --- AFNetworking/AFHTTPClient.h | 151 ++++++++++++++++-------- AFNetworking/AFHTTPRequestOperation.h | 15 ++- AFNetworking/AFURLConnectionOperation.h | 76 +++++++----- 3 files changed, 161 insertions(+), 81 deletions(-) diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index e96592b..895850f 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -23,54 +23,6 @@ #import @class AFHTTPRequestOperation; -@protocol AFHTTPClientOperation; -@protocol AFMultipartFormData; - -/** - Posted when network reachability changes. - The notification object is an `NSNumber` object containing the boolean value for the current network reachability. - This notification contains no information in the `userInfo` dictionary. - - @warning In order for network reachability to be monitored, include the `SystemConfiguration` framework in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (Prefix.pch). - */ -#ifdef _SYSTEMCONFIGURATION_H -extern NSString * const AFNetworkingReachabilityDidChangeNotification; -#endif - -/** - Specifies network reachability of the client to its `baseURL` domain. - */ -#ifdef _SYSTEMCONFIGURATION_H -typedef enum { - AFNetworkReachabilityStatusUnknown = -1, - AFNetworkReachabilityStatusNotReachable = 0, - AFNetworkReachabilityStatusReachableViaWWAN = 1, - AFNetworkReachabilityStatusReachableViaWiFi = 2, -} AFNetworkReachabilityStatus; -#endif - -/** - Specifies the method used to encode parameters into request body. - */ -typedef enum { - AFFormURLParameterEncoding, - AFJSONParameterEncoding, - AFPropertyListParameterEncoding, -} AFHTTPClientParameterEncoding; - -/** - Returns a query string constructed by a set of parameters, using the specified encoding. - - @param parameters The parameters used to construct the query string - @param encoding The encoding to use in constructing the query string. If you are uncertain of the correct encoding, you should use UTF-8 (`NSUTF8StringEncoding`), which is the encoding designated by RFC 3986 as the correct encoding for use in URLs. - - @discussion Query strings are constructed by collecting each key-value pair, percent escaping a string representation of the key-value pair, and then joining the pairs with "&". - - If a query string pair has a an `NSArray` for its value, each member of the array will be represented in the format `field[]=value1&field[]value2`. Otherwise, the pair will be formatted as "field=value". String representations of both keys and values are derived using the `-description` method. The constructed query string does not include the ? character used to delimit the query component. - - @return A percent-escaped query string - */ -extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *parameters, NSStringEncoding encoding); /** `AFHTTPClient` captures the common patterns of communicating with an web application over HTTP. It encapsulates information like base URL, authorization credentials, and HTTP headers, and uses them to construct and manage the execution of HTTP request operations. @@ -110,6 +62,8 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete [NSURL URLWithString:@"foo/" relativeToURL:baseURL]; // http://example.com/v1/foo [NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // http://example.com/foo/ [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/ + + Also important to note is that a trailing slash will be added to any `baseURL` without one, which would otherwise cause unexpected behavior when constructing URLs using paths without a leading slash. ## NSCoding / NSCopying Conformance @@ -118,6 +72,25 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete - Archives and copies of HTTP clients will be initialized with an empty operation queue. - NSCoding cannot serialize / deserialize block properties, so an archive of an HTTP client will not include any reachability callback block that may be set. */ + +#ifdef _SYSTEMCONFIGURATION_H +typedef enum { + AFNetworkReachabilityStatusUnknown = -1, + AFNetworkReachabilityStatusNotReachable = 0, + AFNetworkReachabilityStatusReachableViaWWAN = 1, + AFNetworkReachabilityStatusReachableViaWiFi = 2, +} AFNetworkReachabilityStatus; +#endif + +typedef enum { + AFFormURLParameterEncoding, + AFJSONParameterEncoding, + AFPropertyListParameterEncoding, +} AFHTTPClientParameterEncoding; + +@protocol AFHTTPClientOperation; +@protocol AFMultipartFormData; + @interface AFHTTPClient : NSObject ///--------------------------------------- @@ -443,6 +416,87 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; @end +///---------------- +/// @name Constants +///---------------- + +/** + ### Network Reachability + + The following constants are provided by `AFHTTPClient` as possible network reachability statuses. + + enum { + AFNetworkReachabilityStatusUnknown, + AFNetworkReachabilityStatusNotReachable, + AFNetworkReachabilityStatusReachableViaWWAN, + AFNetworkReachabilityStatusReachableViaWiFi, + } + + `AFNetworkReachabilityStatusUnknown` + The `baseURL` host reachability is not known. + + `AFNetworkReachabilityStatusNotReachable` + The `baseURL` host cannot be reached. + + `AFNetworkReachabilityStatusReachableViaWWAN` + The `baseURL` host can be reached via a cellular connection, such as EDGE or GPRS. + + `AFNetworkReachabilityStatusReachableViaWiFi` + The `baseURL` host can be reached via a Wi-Fi connection. + + ### Parameter Encoding + + The following constants are provided by `AFHTTPClient` as possible methods for serializing parameters into query string or message body values. + + enum { + AFFormURLParameterEncoding, + AFJSONParameterEncoding, + AFPropertyListParameterEncoding, + } + + `AFFormURLParameterEncoding` + Parameters are encoded into field/key pairs in the URL query string for `GET` `HEAD` and `DELETE` requests, and in the message body otherwise. + + `AFJSONParameterEncoding` + Parameters are encoded into JSON in the message body. + + `AFPropertyListParameterEncoding` + Parameters are encoded into a property list in the message body. + */ + +///---------------- +/// @name Functions +///---------------- + +/** + Returns a query string constructed by a set of parameters, using the specified encoding. + + @param parameters The parameters used to construct the query string + @param encoding The encoding to use in constructing the query string. If you are uncertain of the correct encoding, you should use UTF-8 (`NSUTF8StringEncoding`), which is the encoding designated by RFC 3986 as the correct encoding for use in URLs. + + @discussion Query strings are constructed by collecting each key-value pair, percent escaping a string representation of the key-value pair, and then joining the pairs with "&". + + If a query string pair has a an `NSArray` for its value, each member of the array will be represented in the format `field[]=value1&field[]value2`. Otherwise, the pair will be formatted as "field=value". String representations of both keys and values are derived using the `-description` method. The constructed query string does not include the ? character used to delimit the query component. + + @return A percent-escaped query string + */ +extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *parameters, NSStringEncoding encoding); + +///-------------------- +/// @name Notifications +///-------------------- + +/** + Posted when network reachability changes. + The notification object is an `NSNumber` object containing the boolean value for the current network reachability. + This notification contains no information in the `userInfo` dictionary. + + @warning In order for network reachability to be monitored, include the `SystemConfiguration` framework in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (Prefix.pch). + */ +#ifdef _SYSTEMCONFIGURATION_H +extern NSString * const AFNetworkingReachabilityDidChangeNotification; +#endif + #pragma mark - /** @@ -506,4 +560,3 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete - (void)appendString:(NSString *)string; @end - diff --git a/AFNetworking/AFHTTPRequestOperation.h b/AFNetworking/AFHTTPRequestOperation.h index 608a6cb..af94ede 100644 --- a/AFNetworking/AFHTTPRequestOperation.h +++ b/AFNetworking/AFHTTPRequestOperation.h @@ -23,11 +23,6 @@ #import #import "AFURLConnectionOperation.h" -/** - Returns a set of MIME types detected in an HTTP `Accept` or `Content-Type` header. - */ -extern NSSet * AFContentTypesFromHTTPHeader(NSString *string); - /** `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. */ @@ -126,3 +121,13 @@ extern NSSet * AFContentTypesFromHTTPHeader(NSString *string); failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; @end + +///---------------- +/// @name Functions +///---------------- + +/** + Returns a set of MIME types detected in an HTTP `Accept` or `Content-Type` header. + */ +extern NSSet * AFContentTypesFromHTTPHeader(NSString *string); + diff --git a/AFNetworking/AFURLConnectionOperation.h b/AFNetworking/AFURLConnectionOperation.h index ad7ace8..5358ad5 100644 --- a/AFNetworking/AFURLConnectionOperation.h +++ b/AFNetworking/AFURLConnectionOperation.h @@ -22,33 +22,6 @@ #import -/** - Indicates an error occurred in AFNetworking. - - @discussion Error codes for AFNetworkingErrorDomain correspond to codes in NSURLErrorDomain. - */ -extern NSString * const AFNetworkingErrorDomain; - -/** - The corresponding value is an `NSURLRequest` containing the request of the operation associated with an error. This key is only present in the `AFNetworkingErrorDomain`. - */ -extern NSString * const AFNetworkingOperationFailingURLRequestErrorKey; - -/** - The corresponding value is an `NSURLResponse` containing the response of the operation associated with an error. This key is only present in the `AFNetworkingErrorDomain`. - */ -extern NSString * const AFNetworkingOperationFailingURLResponseErrorKey; - -/** - Posted when an operation begins executing. - */ -extern NSString * const AFNetworkingOperationDidStartNotification; - -/** - Posted when an operation finishes. - */ -extern NSString * const AFNetworkingOperationDidFinishNotification; - /** `AFURLConnectionOperation` is an `NSOperation` that implements NSURLConnection delegate methods. @@ -309,3 +282,52 @@ didReceiveResponse:(NSURLResponse *)response; willCacheResponse:(NSCachedURLResponse *)cachedResponse; @end + +///---------------- +/// @name Constants +///---------------- + +/** + ## User info dictionary keys + + These keys may exist in the user info dictionary, in addition to those defined for NSError. + + - `NSString * const AFNetworkingOperationFailingURLRequestErrorKey` + - `NSString * const AFNetworkingOperationFailingURLResponseErrorKey` + + ### Constants + + `AFNetworkingOperationFailingURLRequestErrorKey` + The corresponding value is an `NSURLRequest` containing the request of the operation associated with an error. This key is only present in the `AFNetworkingErrorDomain`. + + `AFNetworkingOperationFailingURLResponseErrorKey` + The corresponding value is an `NSURLResponse` containing the response of the operation associated with an error. This key is only present in the `AFNetworkingErrorDomain`. + + ## Error Domains + + The following error domain is predefined. + + - `NSString * const AFNetworkingErrorDomain` + + ### Constants + + `AFNetworkingErrorDomain` + AFNetworking errors. Error codes for `AFNetworkingErrorDomain` correspond to codes in `NSURLErrorDomain`. + */ +extern NSString * const AFNetworkingErrorDomain; +extern NSString * const AFNetworkingOperationFailingURLRequestErrorKey; +extern NSString * const AFNetworkingOperationFailingURLResponseErrorKey; + +///-------------------- +/// @name Notifications +///-------------------- + +/** + Posted when an operation begins executing. + */ +extern NSString * const AFNetworkingOperationDidStartNotification; + +/** + Posted when an operation finishes. + */ +extern NSString * const AFNetworkingOperationDidFinishNotification; From 5166d5af85d7cb88a827938acbc09539a8b61d23 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Wed, 29 Aug 2012 14:16:27 -0700 Subject: [PATCH 59/76] Specifying Mac OS X in User-Agent (/thanks @tewha) --- AFNetworking/AFHTTPClient.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index af82843..92413e2 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -262,7 +262,7 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) { // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43 [self setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleIdentifierKey], CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0f)]]; #elif __MAC_OS_X_VERSION_MIN_REQUIRED - [self setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (Mac OS %@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]]]; + [self setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (Mac OS X %@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]]]; #endif #ifdef _SYSTEMCONFIGURATION_H From e3307924110bfd54e342cf600c6fb48a0a5bd44b Mon Sep 17 00:00:00 2001 From: Tony Million Date: Thu, 30 Aug 2012 21:51:39 +0100 Subject: [PATCH 60/76] hasAcceptableStatusCode will return true after a network failure --- AFNetworking/AFHTTPRequestOperation.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 26b0eb0..31efc4d 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -173,7 +173,7 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { } - (BOOL)hasAcceptableStatusCode { - NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 200; + NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 0; return ![[self class] acceptableStatusCodes] || [[[self class] acceptableStatusCodes] containsIndex:statusCode]; } From cdbae5a9fbb6d6cec795d981b055878f340dbd0b Mon Sep 17 00:00:00 2001 From: Tony Million Date: Fri, 31 Aug 2012 09:27:43 +0100 Subject: [PATCH 61/76] tests self.response before blindy returning 200 in hasAcceptableStatusCode if self.response is nil then network failure is assumed --- AFNetworking/AFHTTPRequestOperation.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 31efc4d..2539d3a 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -173,7 +173,12 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { } - (BOOL)hasAcceptableStatusCode { - NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 0; + if(!self.response) { + // no response means network failure or such + return NO; + } + + NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 200; return ![[self class] acceptableStatusCodes] || [[[self class] acceptableStatusCodes] containsIndex:statusCode]; } From e445903901084566ab1953dda17f042ea4ec5bca Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Fri, 31 Aug 2012 08:41:57 -0700 Subject: [PATCH 62/76] Adding early return for hasAcceptableContentType --- AFNetworking/AFHTTPRequestOperation.m | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 2539d3a..940a85f 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -173,16 +173,19 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { } - (BOOL)hasAcceptableStatusCode { - if(!self.response) { - // no response means network failure or such + if (!self.response) { return NO; } - + NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 200; return ![[self class] acceptableStatusCodes] || [[[self class] acceptableStatusCodes] containsIndex:statusCode]; } - (BOOL)hasAcceptableContentType { + if (!self.response) { + return NO; + } + return ![[self class] acceptableContentTypes] || [[[self class] acceptableContentTypes] containsObject:[self.response MIMEType]]; } From 1a23b987789033ca5b0349694032283d1b786d78 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Fri, 31 Aug 2012 08:42:53 -0700 Subject: [PATCH 63/76] Using more idiomatic ?: for AFHTTPRequestOperation -setCompletionBlockWithSuccess:failure: --- AFNetworking/AFHTTPRequestOperation.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 940a85f..9d09e1c 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -227,13 +227,13 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { if (self.error) { if (failure) { - dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ + dispatch_async(self.failureCallbackQueue ?: dispatch_get_main_queue(), ^{ failure(self, self.error); }); } } else { if (success) { - dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ + dispatch_async(self.successCallbackQueue ?: dispatch_get_main_queue(), ^{ success(self, self.responseData); }); } From ec0240f6e4d72498cb8343f55ca04e4852512c2e Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Fri, 31 Aug 2012 09:04:54 -0700 Subject: [PATCH 64/76] [Issue #489] Adding userInfo dictionary with current status in reachability changes --- AFNetworking/AFHTTPClient.h | 12 ++++++++++-- AFNetworking/AFHTTPClient.m | 7 ++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index 895850f..76a4a92 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -444,6 +444,14 @@ typedef enum { `AFNetworkReachabilityStatusReachableViaWiFi` The `baseURL` host can be reached via a Wi-Fi connection. + ### Keys for Notification UserInfo Dictionary + + Strings that are used as keys in a userinfo dictionary in a network reachability status change notification. + + `AFNetworkingReachabilityNotificationStatusItem` + A key in the userInfo dictionary in a `AFNetworkingReachabilityDidChangeNotification` notification. + The corresponding value is an `NSNumber` object representing the `AFNetworkReachabilityStatus` value for the current reachability status. + ### Parameter Encoding The following constants are provided by `AFHTTPClient` as possible methods for serializing parameters into query string or message body values. @@ -488,13 +496,13 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete /** Posted when network reachability changes. - The notification object is an `NSNumber` object containing the boolean value for the current network reachability. - This notification contains no information in the `userInfo` dictionary. + This notification assigns no notification object. The `userInfo` dictionary contains an `NSNumber` object under the `AFNetworkingReachabilityNotificationStatusItem` key, representing the `AFNetworkReachabilityStatus` value for the current network reachability. @warning In order for network reachability to be monitored, include the `SystemConfiguration` framework in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (Prefix.pch). */ #ifdef _SYSTEMCONFIGURATION_H extern NSString * const AFNetworkingReachabilityDidChangeNotification; +extern NSString * const AFNetworkingReachabilityNotificationStatusItem; #endif #pragma mark - diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 92413e2..04c99ed 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -41,8 +41,6 @@ #import #endif -NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire.networking.reachability.change"; - @interface AFMultipartFormData : NSObject - (id)initWithURLRequest:(NSMutableURLRequest *)request @@ -55,6 +53,9 @@ NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire #pragma mark - #ifdef _SYSTEMCONFIGURATION_H +NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire.networking.reachability.change"; +NSString * const AFNetworkingReachabilityNotificationStatusItem = @"AFNetworkingReachabilityNotificationStatusItem"; + typedef SCNetworkReachabilityRef AFNetworkReachabilityRef; typedef void (^AFNetworkReachabilityStatusBlock)(AFNetworkReachabilityStatus status); #else @@ -332,7 +333,7 @@ static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused targ block(status); } - [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingReachabilityDidChangeNotification object:[NSNumber numberWithInt:status]]; + [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInteger:status] forKey:AFNetworkingReachabilityNotificationStatusItem]]; } static const void * AFNetworkReachabilityRetainCallback(const void *info) { From 26b5a3b533d9a4661b71054b877350d00dc69cb8 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Fri, 31 Aug 2012 09:09:52 -0700 Subject: [PATCH 65/76] Fixing name of path param in -cancelAllHTTPOperationsWithMethod:path: documentation --- AFNetworking/AFHTTPClient.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index 76a4a92..5af49b3 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -304,7 +304,7 @@ typedef enum { Cancels all operations in the HTTP client's operation queue whose URLs match the specified HTTP method and path. @param method The HTTP method to match for the cancelled requests, such as `GET`, `POST`, `PUT`, or `DELETE`. If `nil`, all request operations with URLs matching the path will be cancelled. - @param url The path to match for the cancelled requests. + @param path The path to match for the cancelled requests. */ - (void)cancelAllHTTPOperationsWithMethod:(NSString *)method path:(NSString *)path; From edb0830128712517df2461b8567860a9d23abfc6 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Fri, 31 Aug 2012 09:13:18 -0700 Subject: [PATCH 66/76] Removing references to AFHTTPClientOperation protocol in documentation --- AFNetworking/AFHTTPClient.h | 9 +++------ AFNetworking/AFImageRequestOperation.m | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index 5af49b3..a20ce8b 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -29,7 +29,7 @@ ## Automatic Content Parsing - Instances of `AFHTTPClient` may specify which types of requests it expects and should handle by registering HTTP operation classes for automatic parsing. Registered classes will determine whether they can handle a particular request, and then construct a request operation accordingly in `enqueueHTTPRequestOperationWithRequest:success:failure`. See `AFHTTPClientOperation` for further details. + Instances of `AFHTTPClient` may specify which types of requests it expects and should handle by registering HTTP operation classes for automatic parsing. Registered classes will determine whether they can handle a particular request, and then construct a request operation accordingly in `enqueueHTTPRequestOperationWithRequest:success:failure`. ## Subclassing Notes @@ -88,7 +88,6 @@ typedef enum { AFPropertyListParameterEncoding, } AFHTTPClientParameterEncoding; -@protocol AFHTTPClientOperation; @protocol AFMultipartFormData; @interface AFHTTPClient : NSObject @@ -174,20 +173,18 @@ typedef enum { /** Attempts to register a subclass of `AFHTTPRequestOperation`, adding it to a chain to automatically generate request operations from a URL request. - @param The subclass of `AFHTTPRequestOperation` to register + @param operationClass The subclass of `AFHTTPRequestOperation` to register @return `YES` if the registration is successful, `NO` otherwise. The only failure condition is if `operationClass` 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 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` */ - (BOOL)registerHTTPOperationClass:(Class)operationClass; /** Unregisters the specified subclass of `AFHTTPRequestOperation`. - @param The class conforming to the `AFHTTPClientOperation` protocol to unregister + @param operationClass The subclass of `AFHTTPRequestOperation` to register @discussion After this method is invoked, `operationClass` is no longer consulted when `requestWithMethod:path:parameters` is invoked. */ diff --git a/AFNetworking/AFImageRequestOperation.m b/AFNetworking/AFImageRequestOperation.m index fbd1e22..a4ca899 100644 --- a/AFNetworking/AFImageRequestOperation.m +++ b/AFNetworking/AFImageRequestOperation.m @@ -186,7 +186,7 @@ static dispatch_queue_t image_request_operation_processing_queue() { } #endif -#pragma mark - AFHTTPClientOperation +#pragma mark - AFHTTPRequestOperation + (NSSet *)acceptableContentTypes { return [NSSet setWithObjects:@"image/tiff", @"image/jpeg", @"image/gif", @"image/png", @"image/ico", @"image/x-icon", @"image/bmp", @"image/x-bmp", @"image/x-xbitmap", @"image/x-win-bitmap", nil]; From 5ddd070607d801f305fbfe6550e81d0b47a8881c Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Fri, 31 Aug 2012 09:53:55 -0700 Subject: [PATCH 67/76] Fixing appledoc compliation errors in documentation Assorted copy edits and reformatting to documentation --- AFNetworking/AFHTTPClient.h | 67 +++++++++++++------------ AFNetworking/AFImageRequestOperation.h | 6 +-- AFNetworking/AFURLConnectionOperation.h | 10 +--- 3 files changed, 38 insertions(+), 45 deletions(-) diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index a20ce8b..97d089b 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -46,23 +46,23 @@ By default, `AFHTTPClient` sets the following HTTP headers: - `Accept-Encoding: gzip` - - `Accept-Language: ([NSLocale preferredLanguages]), en-us;q=0.8` + - `Accept-Language: (comma-delimited preferred languages), en-us;q=0.8` - `User-Agent: (generated user agent)` You can override these HTTP headers or define new ones using `setDefaultHeader:value:`. ## URL Construction Using Relative Paths - Both `requestWithMethod:path:parameters` and `multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:` construct URLs from the path relative to the `baseURL`, using `NSURL +URLWithString:relativeToURL:`. Below are a few examples of how `baseURL` and relative paths interact: - - NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"]; - [NSURL URLWithString:@"foo" relativeToURL:baseURL]; // http://example.com/v1/foo - [NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL]; // http://example.com/v1/foo?bar=baz - [NSURL URLWithString:@"/foo" relativeToURL:baseURL]; // http://example.com/foo - [NSURL URLWithString:@"foo/" relativeToURL:baseURL]; // http://example.com/v1/foo - [NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // http://example.com/foo/ - [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/ + Both `-requestWithMethod:path:parameters:` and `-multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:` construct URLs from the path relative to the `-baseURL`, using `NSURL +URLWithString:relativeToURL:`. Below are a few examples of how `baseURL` and relative paths interact: + NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"]; + [NSURL URLWithString:@"foo" relativeToURL:baseURL]; // http://example.com/v1/foo + [NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL]; // http://example.com/v1/foo?bar=baz + [NSURL URLWithString:@"/foo" relativeToURL:baseURL]; // http://example.com/foo + [NSURL URLWithString:@"foo/" relativeToURL:baseURL]; // http://example.com/v1/foo + [NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // http://example.com/foo/ + [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/ + Also important to note is that a trailing slash will be added to any `baseURL` without one, which would otherwise cause unexpected behavior when constructing URLs using paths without a leading slash. ## NSCoding / NSCopying Conformance @@ -121,7 +121,7 @@ typedef enum { /** The reachability status from the device to the current `baseURL` of the `AFHTTPClient`. - @warning This property requires the `SystemConfiguration` framework. Add it in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (Prefix.pch). + @warning This property requires the `SystemConfiguration` framework. Add it in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (`Prefix.pch`). */ #ifdef _SYSTEMCONFIGURATION_H @property (readonly, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus; @@ -160,7 +160,7 @@ typedef enum { @param block A block object to be executed when the network availability of the `baseURL` host changes.. This block has no return value and takes a single argument which represents the various reachability states from the device to the `baseURL`. - @warning This method requires the `SystemConfiguration` framework. Add it in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (Prefix.pch). + @warning This method requires the `SystemConfiguration` framework. Add it in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (`Prefix.pch`). */ #ifdef _SYSTEMCONFIGURATION_H - (void)setReachabilityStatusChangeBlock:(void (^)(AFNetworkReachabilityStatus status))block; @@ -182,11 +182,9 @@ typedef enum { - (BOOL)registerHTTPOperationClass:(Class)operationClass; /** - Unregisters the specified subclass of `AFHTTPRequestOperation`. - - @param operationClass The subclass of `AFHTTPRequestOperation` to register - - @discussion After this method is invoked, `operationClass` is no longer consulted when `requestWithMethod:path:parameters` is invoked. + Unregisters the specified subclass of `AFHTTPRequestOperation` from the chain of classes consulted when `-requestWithMethod:path:parameters` is called. + + @param operationClass The subclass of `AFHTTPRequestOperation` to register */ - (void)unregisterHTTPOperationClass:(Class)operationClass; @@ -345,7 +343,7 @@ typedef enum { @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the 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 response data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. - @see HTTPRequestOperationWithRequest:success:failure + @see -HTTPRequestOperationWithRequest:success:failure: */ - (void)getPath:(NSString *)path parameters:(NSDictionary *)parameters @@ -360,7 +358,7 @@ typedef enum { @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the 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 response data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. - @see HTTPRequestOperationWithRequest:success:failure + @see -HTTPRequestOperationWithRequest:success:failure: */ - (void)postPath:(NSString *)path parameters:(NSDictionary *)parameters @@ -375,7 +373,7 @@ typedef enum { @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the 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 response data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. - @see HTTPRequestOperationWithRequest:success:failure + @see -HTTPRequestOperationWithRequest:success:failure: */ - (void)putPath:(NSString *)path parameters:(NSDictionary *)parameters @@ -390,7 +388,7 @@ typedef enum { @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the 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 response data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. - @see HTTPRequestOperationWithRequest:success:failure + @see -HTTPRequestOperationWithRequest:success:failure: */ - (void)deletePath:(NSString *)path parameters:(NSDictionary *)parameters @@ -405,7 +403,7 @@ typedef enum { @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the 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 response data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. - @see HTTPRequestOperationWithRequest:success:failure + @see -HTTPRequestOperationWithRequest:success:failure: */ - (void)patchPath:(NSString *)path parameters:(NSDictionary *)parameters @@ -443,7 +441,7 @@ typedef enum { ### Keys for Notification UserInfo Dictionary - Strings that are used as keys in a userinfo dictionary in a network reachability status change notification. + Strings that are used as keys in a `userInfo` dictionary in a network reachability status change notification. `AFNetworkingReachabilityNotificationStatusItem` A key in the userInfo dictionary in a `AFNetworkingReachabilityDidChangeNotification` notification. @@ -495,7 +493,7 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete Posted when network reachability changes. This notification assigns no notification object. The `userInfo` dictionary contains an `NSNumber` object under the `AFNetworkingReachabilityNotificationStatusItem` key, representing the `AFNetworkReachabilityStatus` value for the current network reachability. - @warning In order for network reachability to be monitored, include the `SystemConfiguration` framework in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (Prefix.pch). + @warning In order for network reachability to be monitored, include the `SystemConfiguration` framework in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (`Prefix.pch`). */ #ifdef _SYSTEMCONFIGURATION_H extern NSString * const AFNetworkingReachabilityDidChangeNotification; @@ -505,9 +503,7 @@ extern NSString * const AFNetworkingReachabilityNotificationStatusItem; #pragma mark - /** - The `AFMultipartFormData` protocol defines the methods supported by the parameter in the block argument of `multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:`. - - @see `AFHTTPClient -multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:` + The `AFMultipartFormData` protocol defines the methods supported by the parameter in the block argument of `-multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:`. */ @protocol AFMultipartFormData @@ -517,7 +513,8 @@ extern NSString * const AFNetworkingReachabilityNotificationStatusItem; @param headers The HTTP headers to be appended to the form data. @param body The data to be encoded and appended to the form data. */ -- (void)appendPartWithHeaders:(NSDictionary *)headers body:(NSData *)body; +- (void)appendPartWithHeaders:(NSDictionary *)headers + body:(NSData *)body; /** Appends the HTTP headers `Content-Disposition: form-data; name=#{name}"`, followed by the encoded data and the multipart form boundary. @@ -525,17 +522,21 @@ extern NSString * const AFNetworkingReachabilityNotificationStatusItem; @param data The data to be encoded and appended to the form data. @param name The name to be associated with the specified data. This parameter must not be `nil`. */ -- (void)appendPartWithFormData:(NSData *)data name:(NSString *)name; +- (void)appendPartWithFormData:(NSData *)data + name:(NSString *)name; /** Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary. @param data The data to be encoded and appended to the form data. @param name The name to be associated with the specified data. This parameter must not be `nil`. + @param fileName The filename to be associated with the specified data. This parameter must not be `nil`. @param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`. - @param filename The filename to be associated with the specified data. This parameter must not be `nil`. */ -- (void)appendPartWithFileData:(NSData *)data name:(NSString *)name fileName:(NSString *)fileName mimeType:(NSString *)mimeType; +- (void)appendPartWithFileData:(NSData *)data + name:(NSString *)name + fileName:(NSString *)fileName + mimeType:(NSString *)mimeType; /** Appends the HTTP header `Content-Disposition: file; filename=#{generated filename}; name=#{name}"` and `Content-Type: #{generated mimeType}`, followed by the encoded file data and the multipart form boundary. @@ -548,7 +549,9 @@ extern NSString * const AFNetworkingReachabilityNotificationStatusItem; @discussion The filename and MIME type for this data in the form will be automatically generated, using `NSURLResponse` `-suggestedFilename` and `-MIMEType`, respectively. */ -- (BOOL)appendPartWithFileURL:(NSURL *)fileURL name:(NSString *)name error:(NSError **)error; +- (BOOL)appendPartWithFileURL:(NSURL *)fileURL + name:(NSString *)name + error:(NSError **)error; /** Appends encoded data to the form data. diff --git a/AFNetworking/AFImageRequestOperation.h b/AFNetworking/AFImageRequestOperation.h index f6de586..3162bb2 100644 --- a/AFNetworking/AFImageRequestOperation.h +++ b/AFNetworking/AFImageRequestOperation.h @@ -62,15 +62,11 @@ #if __IPHONE_OS_VERSION_MIN_REQUIRED /** - The scale factor used when interpreting the image data to construct `responseImage`. Specifying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the size property. This is set to the value of `[[UIScreen mainScreen] scale]` by default, which automatically scales images for retina displays, for instance. + The scale factor used when interpreting the image data to construct `responseImage`. Specifying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the size property. This is set to the value of scale of the main screen by default, which automatically scales images for retina displays, for instance. */ @property (nonatomic, assign) CGFloat imageScale; #endif -/** - An image constructed from the response data. If an error occurs during the request, `nil` will be returned, and the `error` property will be set to the error. - */ - /** Creates and returns an `AFImageRequestOperation` object and sets the specified success callback. diff --git a/AFNetworking/AFURLConnectionOperation.h b/AFNetworking/AFURLConnectionOperation.h index 5358ad5..5936797 100644 --- a/AFNetworking/AFURLConnectionOperation.h +++ b/AFNetworking/AFURLConnectionOperation.h @@ -54,7 +54,7 @@ The built-in `completionBlock` provided by `NSOperation` allows for custom behavior to be executed after the request finishes. It is a common pattern for class constructors in subclasses to take callback block parameters, and execute them conditionally in the body of its `completionBlock`. Make sure to handle cancelled operations appropriately when setting a `completionBlock` (e.g. returning early before parsing response data). See the implementation of any of the `AFHTTPRequestOperation` subclasses for an example of this. - @warning Subclasses are strongly discouraged from overriding `setCompletionBlock:`, as `AFURLConnectionOperation`'s implementation includes a workaround to mitigate retain cycles, and what Apple rather ominously refers to as "The Deallocation Problem" (See http://developer.apple.com/library/ios/technotes/tn2109/_index.html#//apple_ref/doc/uid/DTS40010274-CH1-SUBSECTION11) + Subclasses are strongly discouraged from overriding `setCompletionBlock:`, as `AFURLConnectionOperation`'s implementation includes a workaround to mitigate retain cycles, and what Apple rather ominously refers to as ["The Deallocation Problem"](http://developer.apple.com/library/ios/#technotes/tn2109/). ## NSCoding & NSCopying Conformance @@ -69,7 +69,7 @@ - `-copy` and `-copyWithZone:` return a new operation with the `NSURLRequest` of the original. So rather than an exact copy of the operation at that particular instant, the copying mechanism returns a completely new instance, which can be useful for retrying operations. - A copy of an operation will not include the `outputStream` of the original. - - Operation copies do not include `completionBlock`. `completionBlock` often strongly captures a reference to `self`, which, perhaps surprisingly, would otherwise point to the _original_ operation when copied. + - Operation copies do not include `completionBlock`. `completionBlock` often strongly captures a reference to `self`, which, perhaps surprisingly, would otherwise point to the _original_ operation when copied. */ @interface AFURLConnectionOperation : NSOperation @@ -194,10 +194,6 @@ Sets a callback to be called when an undetermined number of bytes have been uploaded to the server. @param block A block object to be called when an undetermined number of bytes have been uploaded to the server. This block has no return value and takes three arguments: the number of bytes written since the last time the upload progress block was called, the total bytes written, and the total bytes expected to be written during the request, as initially determined by the length of the HTTP body. This block may be called multiple times, and will execute on the main thread. - - @discussion This block is called on the main thread. - - @see setDownloadProgressBlock */ - (void)setUploadProgressBlock:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block; @@ -205,8 +201,6 @@ Sets a callback to be called when an undetermined number of bytes have been downloaded from the server. @param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the main thread. - - @see setUploadProgressBlock */ - (void)setDownloadProgressBlock:(void (^)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block; From 70dff01807c1ff7f8f72575d7c43269ae1c07346 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Fri, 31 Aug 2012 16:57:04 -0700 Subject: [PATCH 68/76] Using dispatch_once pattern for initializing UIImageView request operation queue singleton Initializing operation queue with NSOperationQueueDefaultMaxConcurrentOperationCount --- AFNetworking/UIImageView+AFNetworking.m | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/AFNetworking/UIImageView+AFNetworking.m b/AFNetworking/UIImageView+AFNetworking.m index 6de959f..70bd401 100644 --- a/AFNetworking/UIImageView+AFNetworking.m +++ b/AFNetworking/UIImageView+AFNetworking.m @@ -59,10 +59,11 @@ static char kAFImageRequestOperationObjectKey; + (NSOperationQueue *)af_sharedImageRequestOperationQueue { static NSOperationQueue *_af_imageRequestOperationQueue = nil; - if (!_af_imageRequestOperationQueue) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ _af_imageRequestOperationQueue = [[NSOperationQueue alloc] init]; - [_af_imageRequestOperationQueue setMaxConcurrentOperationCount:8]; - } + [_af_imageRequestOperationQueue setMaxConcurrentOperationCount:NSOperationQueueDefaultMaxConcurrentOperationCount]; + }); return _af_imageRequestOperationQueue; } From b614dee5bb938abbfbf6fd2dda8d67b812dabc42 Mon Sep 17 00:00:00 2001 From: Mike Lewis Date: Fri, 31 Aug 2012 23:29:11 -0700 Subject: [PATCH 69/76] Removing setting Accept-Encoding by default. NSURLConnection will set this to the supported formats which is a superset of gzip. (at least in 5.1 it set deflate as well) --- AFNetworking/AFHTTPClient.m | 3 --- 1 file changed, 3 deletions(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 04c99ed..d5af72c 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -251,9 +251,6 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) { self.registeredHTTPOperationClassNames = [NSMutableArray array]; self.defaultHeaders = [NSMutableDictionary dictionary]; - - // Accept-Encoding HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3 - [self setDefaultHeader:@"Accept-Encoding" value:@"gzip"]; // Accept-Language HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 NSString *preferredLanguageCodes = [[NSLocale preferredLanguages] componentsJoinedByString:@", "]; From 858c716c16c479cc8e142a719c90fad0316eaf8f Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Mon, 3 Sep 2012 11:11:24 -0700 Subject: [PATCH 70/76] Re-indenting AFHTTPClient.m --- AFNetworking/AFHTTPClient.m | 110 ++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 04c99ed..b671c9a 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -1,17 +1,17 @@ // AFHTTPClient.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 @@ -43,7 +43,7 @@ @interface AFMultipartFormData : NSObject -- (id)initWithURLRequest:(NSMutableURLRequest *)request +- (id)initWithURLRequest:(NSMutableURLRequest *)request stringEncoding:(NSStringEncoding)encoding; - (NSMutableURLRequest *)requestByFinalizingMultipartFormData; @@ -77,7 +77,7 @@ static NSString * AFBase64EncodedStringFromString(NSString *string) { for (NSUInteger j = i; j < (i + 3); j++) { value <<= 8; if (j < length) { - value |= (0xFF & input[j]); + value |= (0xFF & input[j]); } } @@ -96,7 +96,7 @@ static NSString * AFBase64EncodedStringFromString(NSString *string) { NSString * AFPercentEscapedQueryStringPairMemberFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { // Escape characters that are legal in URIs, but have unintentional semantic significance when used in a query string parameter static NSString * const kAFLegalCharactersToBeEscaped = @":/.?&=;+!@$()~"; - + return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, (CFStringRef)kAFLegalCharactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease]; } @@ -111,7 +111,7 @@ NSString * AFPercentEscapedQueryStringPairMemberFromStringWithEncoding(NSString @end -@implementation AFQueryStringPair +@implementation AFQueryStringPair @synthesize field = _field; @synthesize value = _value; @@ -170,7 +170,7 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) { }]; } else { [mutableQueryStringComponents addObject:[[[AFQueryStringPair alloc] initWithField:key value:value] autorelease]]; - } + } return mutableQueryStringComponents; } @@ -250,22 +250,22 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) { self.registeredHTTPOperationClassNames = [NSMutableArray array]; - self.defaultHeaders = [NSMutableDictionary dictionary]; + self.defaultHeaders = [NSMutableDictionary dictionary]; - // Accept-Encoding HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3 - [self setDefaultHeader:@"Accept-Encoding" value:@"gzip"]; + // Accept-Encoding HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3 + [self setDefaultHeader:@"Accept-Encoding" value:@"gzip"]; - // Accept-Language HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 - NSString *preferredLanguageCodes = [[NSLocale preferredLanguages] componentsJoinedByString:@", "]; - [self setDefaultHeader:@"Accept-Language" value:[NSString stringWithFormat:@"%@, en-us;q=0.8", preferredLanguageCodes]]; - + // Accept-Language HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 + NSString *preferredLanguageCodes = [[NSLocale preferredLanguages] componentsJoinedByString:@", "]; + [self setDefaultHeader:@"Accept-Language" value:[NSString stringWithFormat:@"%@, en-us;q=0.8", preferredLanguageCodes]]; + #if __IPHONE_OS_VERSION_MIN_REQUIRED // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43 [self setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleIdentifierKey], CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0f)]]; #elif __MAC_OS_X_VERSION_MIN_REQUIRED [self setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (Mac OS X %@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]]]; #endif - + #ifdef _SYSTEMCONFIGURATION_H self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown; [self startMonitoringNetworkReachability]; @@ -326,7 +326,7 @@ static AFNetworkReachabilityStatus AFNetworkReachabilityStatusForFlags(SCNetwork return status; } -static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) { +static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) { AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags); AFNetworkReachabilityStatusBlock block = (AFNetworkReachabilityStatusBlock)info; if (block) { @@ -432,20 +432,20 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { #pragma mark - -- (NSMutableURLRequest *)requestWithMethod:(NSString *)method - path:(NSString *)path - parameters:(NSDictionary *)parameters -{ +- (NSMutableURLRequest *)requestWithMethod:(NSString *)method + path:(NSString *)path + parameters:(NSDictionary *)parameters +{ NSURL *url = [NSURL URLWithString:path relativeToURL:self.baseURL]; NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL:url] autorelease]; [request setHTTPMethod:method]; [request setAllHTTPHeaderFields:self.defaultHeaders]; - + if ([method isEqualToString:@"GET"] || [method isEqualToString:@"HEAD"]) { [request setHTTPShouldUsePipelining:YES]; } - if (parameters) { + if (parameters) { if ([method isEqualToString:@"GET"] || [method isEqualToString:@"HEAD"] || [method isEqualToString:@"DELETE"]) { url = [NSURL URLWithString:[[url absoluteString] stringByAppendingFormat:[path rangeOfString:@"?"].location == NSNotFound ? @"?%@" : @"&%@", AFQueryStringFromParametersWithEncoding(parameters, self.stringEncoding)]]; [request setURL:url]; @@ -501,7 +501,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { return [formData requestByFinalizingMultipartFormData]; } -- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest +- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { @@ -542,8 +542,8 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { } } -- (void)enqueueBatchOfHTTPRequestOperationsWithRequests:(NSArray *)requests - progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock +- (void)enqueueBatchOfHTTPRequestOperationsWithRequests:(NSArray *)requests + progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock completionBlock:(void (^)(NSArray *operations))completionBlock { NSMutableArray *mutableOperations = [NSMutableArray array]; @@ -555,8 +555,8 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { [self enqueueBatchOfHTTPRequestOperations:mutableOperations progressBlock:progressBlock completionBlock:completionBlock]; } -- (void)enqueueBatchOfHTTPRequestOperations:(NSArray *)operations - progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock +- (void)enqueueBatchOfHTTPRequestOperations:(NSArray *)operations + progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock completionBlock:(void (^)(NSArray *operations))completionBlock { __block dispatch_group_t dispatchGroup = dispatch_group_create(); @@ -568,7 +568,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { }); dispatch_release(dispatchGroup); }]; - + for (AFHTTPRequestOperation *operation in operations) { AFCompletionBlock originalCompletionBlock = [[operation.completionBlock copy] autorelease]; operation.completionBlock = ^{ @@ -603,8 +603,8 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { #pragma mark - -- (void)getPath:(NSString *)path - parameters:(NSDictionary *)parameters +- (void)getPath:(NSString *)path + parameters:(NSDictionary *)parameters success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { @@ -613,8 +613,8 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { [self enqueueHTTPRequestOperation:operation]; } -- (void)postPath:(NSString *)path - parameters:(NSDictionary *)parameters +- (void)postPath:(NSString *)path + parameters:(NSDictionary *)parameters success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { @@ -623,8 +623,8 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { [self enqueueHTTPRequestOperation:operation]; } -- (void)putPath:(NSString *)path - parameters:(NSDictionary *)parameters +- (void)putPath:(NSString *)path + parameters:(NSDictionary *)parameters success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { @@ -633,8 +633,8 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { [self enqueueHTTPRequestOperation:operation]; } -- (void)deletePath:(NSString *)path - parameters:(NSDictionary *)parameters +- (void)deletePath:(NSString *)path + parameters:(NSDictionary *)parameters success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { @@ -643,8 +643,8 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { [self enqueueHTTPRequestOperation:operation]; } -- (void)patchPath:(NSString *)path - parameters:(NSDictionary *)parameters +- (void)patchPath:(NSString *)path + parameters:(NSDictionary *)parameters success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { @@ -735,7 +735,7 @@ static inline NSString * AFMultipartFormFinalBoundary() { @property (readwrite, nonatomic, retain) NSMutableURLRequest *request; @property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding; @property (readwrite, nonatomic, retain) NSOutputStream *outputStream; -@property (readwrite, nonatomic, copy) NSString *temporaryFilePath; +@property (readwrite, nonatomic, copy) NSString *temporaryFilePath; @end @implementation AFMultipartFormData @@ -744,8 +744,8 @@ static inline NSString * AFMultipartFormFinalBoundary() { @synthesize outputStream = _outputStream; @synthesize temporaryFilePath = _temporaryFilePath; -- (id)initWithURLRequest:(NSMutableURLRequest *)request - stringEncoding:(NSStringEncoding)encoding +- (id)initWithURLRequest:(NSMutableURLRequest *)request + stringEncoding:(NSStringEncoding)encoding { self = [super init]; if (!self) { @@ -785,7 +785,7 @@ static inline NSString * AFMultipartFormFinalBoundary() { return self.request; } - + [self appendData:[AFMultipartFormFinalBoundary() dataUsingEncoding:self.stringEncoding]]; [self.request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", kAFMultipartFormBoundary] forHTTPHeaderField:@"Content-Type"]; @@ -807,8 +807,8 @@ static inline NSString * AFMultipartFormFinalBoundary() { } } -- (void)appendPartWithHeaders:(NSDictionary *)headers - body:(NSData *)body +- (void)appendPartWithHeaders:(NSDictionary *)headers + body:(NSData *)body { [self appendBoundary]; @@ -820,8 +820,8 @@ static inline NSString * AFMultipartFormFinalBoundary() { [self appendData:body]; } -- (void)appendPartWithFormData:(NSData *)data - name:(NSString *)name +- (void)appendPartWithFormData:(NSData *)data + name:(NSString *)name { NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"", name] forKey:@"Content-Disposition"]; @@ -829,11 +829,11 @@ static inline NSString * AFMultipartFormFinalBoundary() { [self appendPartWithHeaders:mutableHeaders body:data]; } -- (void)appendPartWithFileData:(NSData *)data - name:(NSString *)name - fileName:(NSString *)fileName +- (void)appendPartWithFileData:(NSData *)data + name:(NSString *)name + fileName:(NSString *)fileName mimeType:(NSString *)mimeType -{ +{ NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"]; [mutableHeaders setValue:mimeType forKey:@"Content-Type"]; @@ -841,9 +841,9 @@ static inline NSString * AFMultipartFormFinalBoundary() { [self appendPartWithHeaders:mutableHeaders body:data]; } -- (BOOL)appendPartWithFileURL:(NSURL *)fileURL - name:(NSString *)name - error:(NSError **)error +- (BOOL)appendPartWithFileURL:(NSURL *)fileURL + name:(NSString *)name + error:(NSError **)error { if (![fileURL isFileURL]) { NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; @@ -879,7 +879,7 @@ static inline NSString * AFMultipartFormFinalBoundary() { if ([data length] == 0) { return; } - + if ([self.outputStream hasSpaceAvailable]) { const uint8_t *dataBuffer = (uint8_t *) [data bytes]; [self.outputStream write:&dataBuffer[0] maxLength:[data length]]; From e1dafd15ecad6acad6c2fc76f40e1bb4549bbe27 Mon Sep 17 00:00:00 2001 From: Stephan Diederich Date: Tue, 4 Sep 2012 19:24:03 +0200 Subject: [PATCH 71/76] fix warning Xcode warns about a missing prototype which can be fixed by making the (private) method static --- AFNetworking/AFHTTPClient.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index d5af72c..0596022 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -93,7 +93,7 @@ static NSString * AFBase64EncodedStringFromString(NSString *string) { return [[[NSString alloc] initWithData:mutableData encoding:NSASCIIStringEncoding] autorelease]; } -NSString * AFPercentEscapedQueryStringPairMemberFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { +static NSString * AFPercentEscapedQueryStringPairMemberFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { // Escape characters that are legal in URIs, but have unintentional semantic significance when used in a query string parameter static NSString * const kAFLegalCharactersToBeEscaped = @":/.?&=;+!@$()~"; From c5e450f4af4092c113595efb4252016498102ce4 Mon Sep 17 00:00:00 2001 From: Avi Itskovich Date: Tue, 4 Sep 2012 17:32:00 -0400 Subject: [PATCH 72/76] Fix typo in multipart dir warning message --- AFNetworking/AFHTTPClient.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 0596022..0ed05ef 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -705,7 +705,7 @@ static NSString * AFMultipartTemporaryFileDirectoryPath() { NSError *error = nil; if(![[NSFileManager defaultManager] createDirectoryAtPath:multipartTemporaryFilePath withIntermediateDirectories:YES attributes:nil error:&error]) { - NSLog(@"Failed to create multipary temporary file directory at %@", multipartTemporaryFilePath); + NSLog(@"Failed to create multipart temporary file directory at %@", multipartTemporaryFilePath); } }); From c0d7e11449b1f2c392f5aba656ab0706c0c15487 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Fri, 7 Sep 2012 16:45:12 -0700 Subject: [PATCH 73/76] [Issue #505] Handling missing content type correctly --- AFNetworking/AFHTTPRequestOperation.m | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 9d09e1c..1456eca 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -186,7 +186,15 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { return NO; } - return ![[self class] acceptableContentTypes] || [[[self class] acceptableContentTypes] containsObject:[self.response MIMEType]]; + // According to RFC 2616: + // Any HTTP/1.1 message containing an entity-body SHOULD include a Content-Type header field defining the media type of that body. If and only if the media type is not given by a Content-Type field, the recipient MAY attempt to guess the media type via inspection of its content and/or the name extension(s) of the URI used to identify the resource. If the media type remains unknown, the recipient SHOULD treat it as type "application/octet-stream". + // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html + NSString *contentType = [self.response MIMEType]; + if (!contentType) { + contentType = @"application/octet-stream"; + } + + return ![[self class] acceptableContentTypes] || [[[self class] acceptableContentTypes] containsObject:contentType]; } - (void)setSuccessCallbackQueue:(dispatch_queue_t)successCallbackQueue { From 40c73c6588df887abcbae8a52a1ca67a1067ab33 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Thu, 13 Sep 2012 09:43:27 -0700 Subject: [PATCH 74/76] Updating link to documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5eb48b6..ae5cace 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Choose AFNetworking for your next project, or migrate over your existing project - [Download AFNetworking](https://github.com/AFNetworking/AFNetworking/zipball/master) and try out the included Mac and iPhone example apps - Read the ["Getting Started" guide](https://github.com/AFNetworking/AFNetworking/wiki/Getting-Started-with-AFNetworking), [FAQ](https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ), or [other articles in the wiki](https://github.com/AFNetworking/AFNetworking/wiki) -- Check out the [complete documentation](http://afnetworking.org/Documentation/) for a comprehensive look at the APIs available in AFNetworking +- Check out the [complete documentation](http://afnetworking.github.com/AFNetworking/) for a comprehensive look at the APIs available in AFNetworking - Watch the [NSScreencast episode about AFNetworking](http://nsscreencast.com/episodes/6-afnetworking) for a quick introduction to how to use it in your application - Questions? [Stack Overflow](http://stackoverflow.com/questions/tagged/afnetworking) is the best place to find answers From a4508ac997f8e0a1ac41bd3f9d3e01403eed03b5 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Fri, 14 Sep 2012 09:21:23 -0700 Subject: [PATCH 75/76] [Issue #507] Fixing potential issues with output stream runloop scheduling --- AFNetworking/AFHTTPRequestOperation.m | 5 +++++ AFNetworking/AFURLConnectionOperation.m | 15 +++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 1456eca..db62120 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -314,6 +314,11 @@ didReceiveResponse:(NSURLResponse *)response } else { if ([[self.outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey] length] > 0) { self.outputStream = [NSOutputStream outputStreamToMemory]; + + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; + for (NSString *runLoopMode in self.runLoopModes) { + [self.outputStream scheduleInRunLoop:runLoop forMode:runLoopMode]; + } } } } diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index e1c0a4b..073c211 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -179,7 +179,11 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat self.request = urlRequest; self.outputStream = [NSOutputStream outputStreamToMemory]; - + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; + for (NSString *runLoopMode in self.runLoopModes) { + [self.outputStream scheduleInRunLoop:runLoop forMode:runLoopMode]; + } + self.state = AFOperationReadyState; return self; @@ -253,6 +257,10 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat } - (void)setOutputStream:(NSOutputStream *)outputStream { + if (_outputStream == outputStream) { + return; + } + [self willChangeValueForKey:@"outputStream"]; [outputStream retain]; @@ -262,11 +270,6 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat } _outputStream = outputStream; [self didChangeValueForKey:@"outputStream"]; - - NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; - for (NSString *runLoopMode in self.runLoopModes) { - [self.outputStream scheduleInRunLoop:runLoop forMode:runLoopMode]; - } } #if __IPHONE_OS_VERSION_MIN_REQUIRED From b8dff45fd88687b2f608efc9bbed76a99b46a54e Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Fri, 14 Sep 2012 10:17:53 -0700 Subject: [PATCH 76/76] Updating podspec to 0.10.1 --- AFNetworking.podspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AFNetworking.podspec b/AFNetworking.podspec index 904be11..f8ffa44 100644 --- a/AFNetworking.podspec +++ b/AFNetworking.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = 'AFNetworking' - s.version = '0.10.0' + s.version = '0.10.1' s.license = 'MIT' s.summary = 'A delightful iOS and OS X networking framework.' s.homepage = 'https://github.com/AFNetworking/AFNetworking' s.authors = {'Mattt Thompson' => 'm@mattt.me', 'Scott Raymond' => 'sco@scottraymond.net'} - s.source = { :git => 'https://github.com/AFNetworking/AFNetworking.git', :tag => '0.10.0' } + s.source = { :git => 'https://github.com/AFNetworking/AFNetworking.git', :tag => '0.10.1' } s.source_files = 'AFNetworking' s.framework = 'SystemConfiguration' s.prefix_header_contents = "#import "