Merge branch 'master' into experimental-dispatchgroup
This commit is contained in:
commit
7c603a9fad
15 changed files with 61 additions and 106 deletions
|
|
@ -113,15 +113,7 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete
|
||||||
[NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/
|
[NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@interface AFHTTPClient : NSObject {
|
@interface AFHTTPClient : NSObject
|
||||||
@private
|
|
||||||
NSURL *_baseURL;
|
|
||||||
NSStringEncoding _stringEncoding;
|
|
||||||
AFHTTPClientParameterEncoding _parameterEncoding;
|
|
||||||
NSMutableArray *_registeredHTTPOperationClassNames;
|
|
||||||
NSMutableDictionary *_defaultHeaders;
|
|
||||||
NSOperationQueue *_operationQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
///---------------------------------------
|
///---------------------------------------
|
||||||
/// @name Accessing HTTP Client Properties
|
/// @name Accessing HTTP Client Properties
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,7 @@
|
||||||
/**
|
/**
|
||||||
`AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request.
|
`AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request.
|
||||||
*/
|
*/
|
||||||
@interface AFHTTPRequestOperation : AFURLConnectionOperation {
|
@interface AFHTTPRequestOperation : AFURLConnectionOperation
|
||||||
@private
|
|
||||||
NSIndexSet *_acceptableStatusCodes;
|
|
||||||
NSSet *_acceptableContentTypes;
|
|
||||||
NSError *_HTTPError;
|
|
||||||
dispatch_queue_t _successCallbackQueue;
|
|
||||||
dispatch_queue_t _failureCallbackQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
///----------------------------------------------
|
///----------------------------------------------
|
||||||
/// @name Getting HTTP URL Connection Information
|
/// @name Getting HTTP URL Connection Information
|
||||||
|
|
|
||||||
|
|
@ -49,15 +49,7 @@
|
||||||
- `image/x-xbitmap`
|
- `image/x-xbitmap`
|
||||||
- `image/x-win-bitmap`
|
- `image/x-win-bitmap`
|
||||||
*/
|
*/
|
||||||
@interface AFImageRequestOperation : AFHTTPRequestOperation {
|
@interface AFImageRequestOperation : AFHTTPRequestOperation
|
||||||
@private
|
|
||||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
|
||||||
UIImage *_responseImage;
|
|
||||||
CGFloat _imageScale;
|
|
||||||
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
|
|
||||||
NSImage *_responseImage;
|
|
||||||
#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.
|
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.
|
||||||
|
|
|
||||||
|
|
@ -170,9 +170,7 @@ static dispatch_queue_t image_request_operation_processing_queue() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self willChangeValueForKey:@"imageScale"];
|
|
||||||
_imageScale = imageScale;
|
_imageScale = imageScale;
|
||||||
[self didChangeValueForKey:@"imageScale"];
|
|
||||||
|
|
||||||
self.responseImage = nil;
|
self.responseImage = nil;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,11 +35,7 @@
|
||||||
|
|
||||||
@warning JSON parsing will automatically use JSONKit, SBJSON, YAJL, or NextiveJSON, if provided. Otherwise, the built-in `NSJSONSerialization` class is used, if available (iOS 5.0 and Mac OS 10.7). If the build target does not either support `NSJSONSerialization` or include a third-party JSON library, a runtime exception will be thrown when attempting to parse a JSON request.
|
@warning JSON parsing will automatically use JSONKit, SBJSON, YAJL, or NextiveJSON, if provided. Otherwise, the built-in `NSJSONSerialization` class is used, if available (iOS 5.0 and Mac OS 10.7). If the build target does not either support `NSJSONSerialization` or include a third-party JSON library, a runtime exception will be thrown when attempting to parse a JSON request.
|
||||||
*/
|
*/
|
||||||
@interface AFJSONRequestOperation : AFHTTPRequestOperation {
|
@interface AFJSONRequestOperation : AFHTTPRequestOperation
|
||||||
@private
|
|
||||||
id _responseJSON;
|
|
||||||
NSError *_JSONError;
|
|
||||||
}
|
|
||||||
|
|
||||||
///----------------------------
|
///----------------------------
|
||||||
/// @name Getting Response Data
|
/// @name Getting Response Data
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,7 @@
|
||||||
/**
|
/**
|
||||||
`AFNetworkActivityIndicatorManager` manages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a network request operation has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero.
|
`AFNetworkActivityIndicatorManager` manages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a network request operation has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero.
|
||||||
*/
|
*/
|
||||||
@interface AFNetworkActivityIndicatorManager : NSObject {
|
@interface AFNetworkActivityIndicatorManager : NSObject
|
||||||
@private
|
|
||||||
NSInteger _activityCount;
|
|
||||||
BOOL _enabled;
|
|
||||||
NSTimer *_activityIndicatorVisibilityTimer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A Boolean value indicating whether the manager is enabled.
|
A Boolean value indicating whether the manager is enabled.
|
||||||
|
|
@ -44,6 +39,11 @@
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, assign, getter = isEnabled) BOOL enabled;
|
@property (nonatomic, assign, getter = isEnabled) BOOL enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
A Boolean value indicating whether the network activity indicator is currently displayed in the status bar.
|
||||||
|
*/
|
||||||
|
@property (readonly, nonatomic, assign) BOOL isNetworkActivityIndicatorVisible;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the shared network activity indicator manager object for the system.
|
Returns the shared network activity indicator manager object for the system.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#import "AFNetworkActivityIndicatorManager.h"
|
#import "AFNetworkActivityIndicatorManager.h"
|
||||||
|
|
||||||
#import "AFHTTPRequestOperation.h"
|
#import "AFHTTPRequestOperation.h"
|
||||||
|
#import <libkern/OSAtomic.h>
|
||||||
|
|
||||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||||
static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25;
|
static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25;
|
||||||
|
|
@ -72,11 +73,7 @@ static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25;
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setActivityCount:(NSInteger)activityCount {
|
- (void)updateNetworkActivityIndicatorVisibilityDelayed {
|
||||||
[self willChangeValueForKey:@"activityCount"];
|
|
||||||
_activityCount = MAX(activityCount, 0);
|
|
||||||
[self didChangeValueForKey:@"activityCount"];
|
|
||||||
|
|
||||||
if (self.enabled) {
|
if (self.enabled) {
|
||||||
// Delay hiding of activity indicator for a short interval, to avoid flickering
|
// Delay hiding of activity indicator for a short interval, to avoid flickering
|
||||||
if (![self isNetworkActivityIndicatorVisible]) {
|
if (![self isNetworkActivityIndicatorVisible]) {
|
||||||
|
|
@ -90,23 +87,41 @@ static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isNetworkActivityIndicatorVisible {
|
- (BOOL)isNetworkActivityIndicatorVisible {
|
||||||
return self.activityCount > 0;
|
return _activityCount > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateNetworkActivityIndicatorVisibility {
|
- (void)updateNetworkActivityIndicatorVisibility {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:[self isNetworkActivityIndicatorVisible]];
|
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:[self isNetworkActivityIndicatorVisible]];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not exposed, but used if activityCount is set via KVC.
|
||||||
|
- (void)setActivityCount:(NSInteger)activityCount {
|
||||||
|
__sync_swap(&_activityCount, activityCount);
|
||||||
|
[self updateNetworkActivityIndicatorVisibilityDelayed];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)incrementActivityCount {
|
- (void)incrementActivityCount {
|
||||||
@synchronized(self) {
|
[self willChangeValueForKey:@"activityCount"];
|
||||||
self.activityCount += 1;
|
OSAtomicIncrement32((int32_t*)&_activityCount);
|
||||||
}
|
[self didChangeValueForKey:@"activityCount"];
|
||||||
|
[self updateNetworkActivityIndicatorVisibilityDelayed];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)decrementActivityCount {
|
- (void)decrementActivityCount {
|
||||||
@synchronized(self) {
|
[self willChangeValueForKey:@"activityCount"];
|
||||||
self.activityCount -= 1;
|
bool success;
|
||||||
|
do {
|
||||||
|
int32_t currentCount = _activityCount;
|
||||||
|
success = OSAtomicCompareAndSwap32(currentCount, MIN(currentCount - 1, currentCount), &_activityCount);
|
||||||
|
} while(!success);
|
||||||
|
[self didChangeValueForKey:@"activityCount"];
|
||||||
|
[self updateNetworkActivityIndicatorVisibilityDelayed];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (NSSet *)keyPathsForValuesAffectingIsNetworkActivityIndicatorVisible {
|
||||||
|
return [NSSet setWithObject:@"activityCount"];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
||||||
|
|
@ -32,13 +32,7 @@
|
||||||
|
|
||||||
- `application/x-plist`
|
- `application/x-plist`
|
||||||
*/
|
*/
|
||||||
@interface AFPropertyListRequestOperation : AFHTTPRequestOperation {
|
@interface AFPropertyListRequestOperation : AFHTTPRequestOperation
|
||||||
@private
|
|
||||||
id _responsePropertyList;
|
|
||||||
NSPropertyListFormat _propertyListFormat;
|
|
||||||
NSPropertyListReadOptions _propertyListReadOptions;
|
|
||||||
NSError *_propertyListError;
|
|
||||||
}
|
|
||||||
|
|
||||||
///----------------------------
|
///----------------------------
|
||||||
/// @name Getting Response Data
|
/// @name Getting Response Data
|
||||||
|
|
|
||||||
|
|
@ -75,24 +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.
|
@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
|
||||||
@private
|
|
||||||
unsigned short _state;
|
|
||||||
BOOL _cancelled;
|
|
||||||
NSRecursiveLock *_lock;
|
|
||||||
|
|
||||||
NSSet *_runLoopModes;
|
|
||||||
|
|
||||||
NSURLConnection *_connection;
|
|
||||||
NSURLRequest *_request;
|
|
||||||
NSHTTPURLResponse *_response;
|
|
||||||
NSError *_error;
|
|
||||||
|
|
||||||
NSData *_responseData;
|
|
||||||
NSInteger _totalBytesRead;
|
|
||||||
NSMutableData *_dataAccumulator;
|
|
||||||
NSOutputStream *_outputStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
///-------------------------------
|
///-------------------------------
|
||||||
/// @name Accessing Run Loop Modes
|
/// @name Accessing Run Loop Modes
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
|
||||||
|
|
||||||
@interface AFURLConnectionOperation ()
|
@interface AFURLConnectionOperation ()
|
||||||
@property (readwrite, nonatomic, assign) AFOperationState state;
|
@property (readwrite, nonatomic, assign) AFOperationState state;
|
||||||
|
@property (readwrite, nonatomic, assign, getter = isCancelled) BOOL cancelled;
|
||||||
@property (readwrite, nonatomic, retain) NSRecursiveLock *lock;
|
@property (readwrite, nonatomic, retain) NSRecursiveLock *lock;
|
||||||
@property (readwrite, nonatomic, retain) NSURLConnection *connection;
|
@property (readwrite, nonatomic, retain) NSURLConnection *connection;
|
||||||
@property (readwrite, nonatomic, retain) NSURLRequest *request;
|
@property (readwrite, nonatomic, retain) NSURLRequest *request;
|
||||||
|
|
@ -106,6 +107,7 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
|
||||||
|
|
||||||
@implementation AFURLConnectionOperation
|
@implementation AFURLConnectionOperation
|
||||||
@synthesize state = _state;
|
@synthesize state = _state;
|
||||||
|
@synthesize cancelled = _cancelled;
|
||||||
@synthesize connection = _connection;
|
@synthesize connection = _connection;
|
||||||
@synthesize runLoopModes = _runLoopModes;
|
@synthesize runLoopModes = _runLoopModes;
|
||||||
@synthesize request = _request;
|
@synthesize request = _request;
|
||||||
|
|
@ -304,10 +306,6 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
|
||||||
return self.state == AFHTTPOperationFinishedState;
|
return self.state == AFHTTPOperationFinishedState;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isCancelled {
|
|
||||||
return _cancelled;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isConcurrent {
|
- (BOOL)isConcurrent {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,7 @@
|
||||||
|
|
||||||
When `AFXMLRequestOperation` is registered with `AFHTTPClient`, the response object in the success callback of `HTTPRequestOperationWithRequest:success:failure:` will be an instance of `NSXMLParser`. On platforms that support `NSXMLDocument`, you have the option to ignore the response object, and simply use the `responseXMLDocument` property of the operation argument of the callback.
|
When `AFXMLRequestOperation` is registered with `AFHTTPClient`, the response object in the success callback of `HTTPRequestOperationWithRequest:success:failure:` will be an instance of `NSXMLParser`. On platforms that support `NSXMLDocument`, you have the option to ignore the response object, and simply use the `responseXMLDocument` property of the operation argument of the callback.
|
||||||
*/
|
*/
|
||||||
@interface AFXMLRequestOperation : AFHTTPRequestOperation {
|
@interface AFXMLRequestOperation : AFHTTPRequestOperation
|
||||||
@private
|
|
||||||
NSXMLParser *_responseXMLParser;
|
|
||||||
#if __MAC_OS_X_VERSION_MIN_REQUIRED
|
|
||||||
NSXMLDocument *_responseXMLDocument;
|
|
||||||
#endif
|
|
||||||
NSError *_XMLError;
|
|
||||||
}
|
|
||||||
|
|
||||||
///----------------------------
|
///----------------------------
|
||||||
/// @name Getting Response Data
|
/// @name Getting Response Data
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
@interface AFImageCache : NSCache
|
@interface AFImageCache : NSCache
|
||||||
- (UIImage *)cachedImageForRequest:(NSURLRequest *)request;
|
- (UIImage *)cachedImageForRequest:(NSURLRequest *)request;
|
||||||
- (void)cacheImageData:(NSData *)imageData
|
- (void)cacheImage:(UIImage *)image
|
||||||
forRequest:(NSURLRequest *)request;
|
forRequest:(NSURLRequest *)request;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
@ -121,7 +121,7 @@ static char kAFImageRequestOperationObjectKey;
|
||||||
success(operation.request, operation.response, responseObject);
|
success(operation.request, operation.response, responseObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[[self class] af_sharedImageCache] cacheImageData:operation.responseData forRequest:urlRequest];
|
[[[self class] af_sharedImageCache] cacheImage:responseObject forRequest:urlRequest];
|
||||||
|
|
||||||
self.af_imageRequestOperation = nil;
|
self.af_imageRequestOperation = nil;
|
||||||
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
|
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
|
||||||
|
|
@ -162,18 +162,13 @@ static inline NSString * AFImageCacheKeyFromURLRequest(NSURLRequest *request) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
UIImage *image = [UIImage imageWithData:[self objectForKey:AFImageCacheKeyFromURLRequest(request)]];
|
return [self objectForKey:AFImageCacheKeyFromURLRequest(request)];
|
||||||
if (image) {
|
|
||||||
return [UIImage imageWithCGImage:[image CGImage] scale:[[UIScreen mainScreen] scale] orientation:image.imageOrientation];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return image;
|
- (void)cacheImage:(UIImage *)image
|
||||||
}
|
|
||||||
|
|
||||||
- (void)cacheImageData:(NSData *)imageData
|
|
||||||
forRequest:(NSURLRequest *)request
|
forRequest:(NSURLRequest *)request
|
||||||
{
|
{
|
||||||
[self setObject:[NSPurgeableData dataWithData:imageData] forKey:AFImageCacheKeyFromURLRequest(request)];
|
[self setObject:image forKey:AFImageCacheKeyFromURLRequest(request)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,10 @@
|
||||||
self.navigationItem.rightBarButtonItem.enabled = NO;
|
self.navigationItem.rightBarButtonItem.enabled = NO;
|
||||||
|
|
||||||
[Tweet publicTimelineTweetsWithBlock:^(NSArray *tweets) {
|
[Tweet publicTimelineTweetsWithBlock:^(NSArray *tweets) {
|
||||||
|
if (tweets) {
|
||||||
_tweets = tweets;
|
_tweets = tweets;
|
||||||
[self.tableView reloadData];
|
[self.tableView reloadData];
|
||||||
|
}
|
||||||
|
|
||||||
[_activityIndicatorView stopAnimating];
|
[_activityIndicatorView stopAnimating];
|
||||||
self.navigationItem.rightBarButtonItem.enabled = YES;
|
self.navigationItem.rightBarButtonItem.enabled = YES;
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,12 @@
|
||||||
}
|
}
|
||||||
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
|
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
|
||||||
NSLog(@"Error: %@", error);
|
NSLog(@"Error: %@", error);
|
||||||
|
|
||||||
|
[[[UIAlertView alloc] initWithTitle:@"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Ok", nil] show];
|
||||||
|
|
||||||
|
if (block) {
|
||||||
|
block(nil);
|
||||||
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setTweet:(Tweet *)tweet {
|
- (void)setTweet:(Tweet *)tweet {
|
||||||
[self willChangeValueForKey:@"tweet"];
|
|
||||||
_tweet = tweet;
|
_tweet = tweet;
|
||||||
[self didChangeValueForKey:@"tweet"];
|
|
||||||
|
|
||||||
self.textLabel.text = _tweet.user.username;
|
self.textLabel.text = _tweet.user.username;
|
||||||
self.detailTextLabel.text = _tweet.text;
|
self.detailTextLabel.text = _tweet.text;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue