From a8210a93bb4ab13e7cbcb32518f9f0f5f737101a Mon Sep 17 00:00:00 2001 From: Eric Patey Date: Tue, 10 Jul 2012 21:12:54 -0400 Subject: [PATCH 01/35] 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 c161a420339fa680da53f80d8848165f3859ac04 Mon Sep 17 00:00:00 2001 From: "tomas.a" Date: Thu, 12 Jul 2012 17:48:12 +0200 Subject: [PATCH 02/35] 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 03/35] 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 04/35] 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 05/35] 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 06/35] 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 07/35] 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 08/35] [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 09/35] 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 10/35] 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 11/35] 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 12/35] 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 13/35] 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 14/35] 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 15/35] 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 16/35] [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 17/35] 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 18/35] 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 19/35] 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 20/35] 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 21/35] 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 22/35] 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 23/35] 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 24/35] 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 25/35] [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 26/35] 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 27/35] 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 28/35] 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 29/35] 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 30/35] 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 31/35] 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 32/35] 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 33/35] 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 34/35] 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 35/35] 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; }