Merge branch 'master' into experimental-1.0RC1
This commit is contained in:
commit
9e73238a7b
7 changed files with 106 additions and 68 deletions
|
|
@ -125,7 +125,8 @@ NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSStringEn
|
|||
@property (readwrite, nonatomic, retain) id key;
|
||||
@property (readwrite, nonatomic, retain) id value;
|
||||
|
||||
- (id)initWithKey:(NSString *)key value:(NSString *)value;
|
||||
- (id)initWithKey:(id)key value:(id)value;
|
||||
- (NSString *)URLEncodedStringValueWithEncoding:(NSStringEncoding)stringEncoding;
|
||||
|
||||
@end
|
||||
|
||||
|
|
@ -133,7 +134,7 @@ NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSStringEn
|
|||
@synthesize key = _key;
|
||||
@synthesize value = _value;
|
||||
|
||||
- (id)initWithKey:(NSString *)key value:(NSString *)value {
|
||||
- (id)initWithKey:(id)key value:(id)value {
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
|
|
@ -151,55 +152,56 @@ NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSStringEn
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"%@=%@", self.key, self.value];
|
||||
- (NSString *)URLEncodedStringValueWithEncoding:(NSStringEncoding)stringEncoding {
|
||||
return [NSString stringWithFormat:@"%@=%@", self.key, AFURLEncodedStringFromStringWithEncoding([self.value description], stringEncoding)];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
extern NSArray * AFQueryStringComponentsFromKeyAndValueWithEncoding(NSString *key, id value, NSStringEncoding stringEncoding);
|
||||
extern NSArray * AFQueryStringComponentsFromKeyAndDictionaryValueWithEncoding(NSString *key, NSDictionary *value, NSStringEncoding stringEncoding);
|
||||
extern NSArray * AFQueryStringComponentsFromKeyAndArrayValueWithEncoding(NSString *key, NSArray *value, NSStringEncoding stringEncoding);
|
||||
extern NSArray * AFQueryStringComponentsFromKeyAndValue(NSString *key, id value);
|
||||
extern NSArray * AFQueryStringComponentsFromKeyAndDictionaryValue(NSString *key, NSDictionary *value);
|
||||
extern NSArray * AFQueryStringComponentsFromKeyAndArrayValue(NSString *key, NSArray *value);
|
||||
|
||||
NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *parameters, NSStringEncoding stringEncoding) {
|
||||
return [[AFQueryStringComponentsFromKeyAndValueWithEncoding(nil, parameters, stringEncoding) valueForKeyPath:@"description"] componentsJoinedByString:@"&"];
|
||||
NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *parameters, NSStringEncoding stringEncoding) {
|
||||
NSMutableArray *mutableComponents = [NSMutableArray array];
|
||||
for (AFQueryStringComponent *component in AFQueryStringComponentsFromKeyAndValue(nil, parameters)) {
|
||||
[mutableComponents addObject:[component URLEncodedStringValueWithEncoding:stringEncoding]];
|
||||
}
|
||||
|
||||
return [mutableComponents componentsJoinedByString:@"&"];
|
||||
}
|
||||
|
||||
AFQueryStringComponent * AFQueryStringComponentFromKeyAndValueWithEncoding(id key, id value, NSStringEncoding stringEncoding) {
|
||||
return [[[AFQueryStringComponent alloc] initWithKey:AFURLEncodedStringFromStringWithEncoding([key description], stringEncoding) value:AFURLEncodedStringFromStringWithEncoding([value description], stringEncoding)] autorelease];
|
||||
}
|
||||
|
||||
NSArray * AFQueryStringComponentsFromKeyAndValueWithEncoding(NSString *key, id value, NSStringEncoding stringEncoding) {
|
||||
NSArray * AFQueryStringComponentsFromKeyAndValue(NSString *key, id value) {
|
||||
NSMutableArray *mutableQueryStringComponents = [NSMutableArray array];
|
||||
|
||||
if([value isKindOfClass:[NSDictionary class]]) {
|
||||
[mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndDictionaryValueWithEncoding(key, value, stringEncoding)];
|
||||
[mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndDictionaryValue(key, value)];
|
||||
} else if([value isKindOfClass:[NSArray class]]) {
|
||||
[mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndArrayValueWithEncoding(key, value, stringEncoding)];
|
||||
[mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndArrayValue(key, value)];
|
||||
} else {
|
||||
[mutableQueryStringComponents addObject:AFQueryStringComponentFromKeyAndValueWithEncoding(key, value, stringEncoding)];
|
||||
[mutableQueryStringComponents addObject:[[[AFQueryStringComponent alloc] initWithKey:key value:value] autorelease]];
|
||||
}
|
||||
|
||||
return mutableQueryStringComponents;
|
||||
}
|
||||
|
||||
NSArray * AFQueryStringComponentsFromKeyAndDictionaryValueWithEncoding(NSString *key, NSDictionary *value, NSStringEncoding stringEncoding){
|
||||
NSArray * AFQueryStringComponentsFromKeyAndDictionaryValue(NSString *key, NSDictionary *value){
|
||||
NSMutableArray *mutableQueryStringComponents = [NSMutableArray array];
|
||||
|
||||
[value enumerateKeysAndObjectsUsingBlock:^(id k, id v, BOOL *stop) {
|
||||
[mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndValueWithEncoding((key ? [NSString stringWithFormat:@"%@[%@]", key, k] : k), v, stringEncoding)];
|
||||
[value enumerateKeysAndObjectsUsingBlock:^(id nestedKey, id nestedValue, BOOL *stop) {
|
||||
[mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndValue((key ? [NSString stringWithFormat:@"%@[%@]", key, nestedKey] : nestedKey), nestedValue)];
|
||||
}];
|
||||
|
||||
return mutableQueryStringComponents;
|
||||
}
|
||||
|
||||
NSArray * AFQueryStringComponentsFromKeyAndArrayValueWithEncoding(NSString *key, NSArray *value, NSStringEncoding stringEncoding) {
|
||||
NSArray * AFQueryStringComponentsFromKeyAndArrayValue(NSString *key, NSArray *value) {
|
||||
NSMutableArray *mutableQueryStringComponents = [NSMutableArray array];
|
||||
|
||||
[value enumerateObjectsUsingBlock:^(id v, NSUInteger idx, BOOL *stop) {
|
||||
[mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndValueWithEncoding([NSString stringWithFormat:@"%@[]", key], v, stringEncoding)];
|
||||
[value enumerateObjectsUsingBlock:^(id nestedValue, NSUInteger idx, BOOL *stop) {
|
||||
[mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndValue([NSString stringWithFormat:@"%@[]", key], nestedValue)];
|
||||
}];
|
||||
|
||||
return mutableQueryStringComponents;
|
||||
|
|
@ -496,8 +498,15 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
|
|||
NSMutableURLRequest *request = [self requestWithMethod:method path:path parameters:nil];
|
||||
__block AFMultipartFormData *formData = [[AFMultipartFormData alloc] initWithStringEncoding:self.stringEncoding];
|
||||
|
||||
for (AFQueryStringComponent *component in AFQueryStringComponentsFromKeyAndValueWithEncoding(nil, parameters, self.stringEncoding)) {
|
||||
[formData appendPartWithFormData:[component.value dataUsingEncoding:self.stringEncoding] name:component.key];
|
||||
for (AFQueryStringComponent *component in AFQueryStringComponentsFromKeyAndValue(nil, parameters)) {
|
||||
NSData *data = nil;
|
||||
if ([component.value isKindOfClass:[NSData class]]) {
|
||||
data = component.value;
|
||||
} else {
|
||||
data = [[component.value description] dataUsingEncoding:self.stringEncoding];
|
||||
}
|
||||
|
||||
[formData appendPartWithFormData:data name:[component.key description]];
|
||||
}
|
||||
|
||||
if (block) {
|
||||
|
|
|
|||
|
|
@ -26,9 +26,11 @@ NSData * AFJSONEncode(id object, NSError **error) {
|
|||
NSData *data = nil;
|
||||
|
||||
SEL _JSONKitSelector = NSSelectorFromString(@"JSONDataWithOptions:error:");
|
||||
SEL _SBJSONSelector = NSSelectorFromString(@"JSONRepresentation");
|
||||
SEL _YAJLSelector = NSSelectorFromString(@"yajl_JSONString");
|
||||
|
||||
id _SBJsonWriterClass = NSClassFromString(@"SBJsonWriter");
|
||||
SEL _SBJsonWriterSelector = NSSelectorFromString(@"dataWithObject:");
|
||||
|
||||
id _NXJsonSerializerClass = NSClassFromString(@"NXJsonSerializer");
|
||||
SEL _NXJsonSerializerSelector = NSSelectorFromString(@"serialize:");
|
||||
|
||||
|
|
@ -54,16 +56,17 @@ NSData * AFJSONEncode(id object, NSError **error) {
|
|||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&data];
|
||||
} else if (_SBJSONSelector && [object respondsToSelector:_SBJSONSelector]) {
|
||||
NSString *JSONString = nil;
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[object methodSignatureForSelector:_SBJSONSelector]];
|
||||
invocation.target = object;
|
||||
invocation.selector = _SBJSONSelector;
|
||||
} else if (_SBJsonWriterClass && [_SBJsonWriterClass instancesRespondToSelector:_SBJsonWriterSelector]) {
|
||||
id writer = [[_SBJsonWriterClass alloc] init];
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[writer methodSignatureForSelector:_SBJsonWriterSelector]];
|
||||
invocation.target = writer;
|
||||
invocation.selector = _SBJsonWriterSelector;
|
||||
|
||||
[invocation setArgument:&object atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&JSONString];
|
||||
|
||||
data = [JSONString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
[invocation getReturnValue:&data];
|
||||
[writer release];
|
||||
} else if (_YAJLSelector && [object respondsToSelector:_YAJLSelector]) {
|
||||
@try {
|
||||
NSString *JSONString = nil;
|
||||
|
|
@ -119,9 +122,11 @@ id AFJSONDecode(NSData *data, NSError **error) {
|
|||
id JSON = nil;
|
||||
|
||||
SEL _JSONKitSelector = NSSelectorFromString(@"objectFromJSONDataWithParseOptions:error:");
|
||||
SEL _SBJSONSelector = NSSelectorFromString(@"JSONValue");
|
||||
SEL _YAJLSelector = NSSelectorFromString(@"yajl_JSONWithOptions:error:");
|
||||
|
||||
id _SBJSONParserClass = NSClassFromString(@"SBJsonParser");
|
||||
SEL _SBJSONParserSelector = NSSelectorFromString(@"objectWithData:");
|
||||
|
||||
id _NSJSONSerializationClass = NSClassFromString(@"NSJSONSerialization");
|
||||
SEL _NSJSONSerializationSelector = NSSelectorFromString(@"JSONObjectWithData:options:error:");
|
||||
|
||||
|
|
@ -143,20 +148,22 @@ id AFJSONDecode(NSData *data, NSError **error) {
|
|||
NSUInteger parseOptionFlags = 0;
|
||||
[invocation setArgument:&parseOptionFlags atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
if (error != NULL) {
|
||||
[invocation setArgument:error atIndex:3];
|
||||
[invocation setArgument:&error atIndex:3];
|
||||
}
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&JSON];
|
||||
} else if (_SBJSONSelector && [NSString instancesRespondToSelector:_SBJSONSelector]) {
|
||||
// Create a string representation of JSON, to use SBJSON -`JSONValue` category method
|
||||
NSString *string = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[string methodSignatureForSelector:_SBJSONSelector]];
|
||||
invocation.target = string;
|
||||
invocation.selector = _SBJSONSelector;
|
||||
} else if (_SBJSONParserClass && [_SBJSONParserClass instancesRespondToSelector:_SBJSONParserSelector]) {
|
||||
id parser = [[_SBJSONParserClass alloc] init];
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[parser methodSignatureForSelector:_SBJSONParserSelector]];
|
||||
invocation.target = parser;
|
||||
invocation.selector = _SBJSONParserSelector;
|
||||
|
||||
[invocation setArgument:&data atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&JSON];
|
||||
[parser release];
|
||||
} else if (_YAJLSelector && [data respondsToSelector:_YAJLSelector]) {
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[data methodSignatureForSelector:_YAJLSelector]];
|
||||
invocation.target = data;
|
||||
|
|
@ -165,7 +172,7 @@ id AFJSONDecode(NSData *data, NSError **error) {
|
|||
NSUInteger yajlParserOptions = 0;
|
||||
[invocation setArgument:&yajlParserOptions atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
if (error != NULL) {
|
||||
[invocation setArgument:error atIndex:3];
|
||||
[invocation setArgument:&error atIndex:3];
|
||||
}
|
||||
|
||||
[invocation invoke];
|
||||
|
|
@ -178,7 +185,7 @@ id AFJSONDecode(NSData *data, NSError **error) {
|
|||
|
||||
[invocation setArgument:&data atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
if (error != NULL) {
|
||||
[invocation setArgument:error atIndex:3];
|
||||
[invocation setArgument:&error atIndex:3];
|
||||
}
|
||||
[invocation setArgument:&nullOption atIndex:4];
|
||||
|
||||
|
|
@ -196,7 +203,7 @@ id AFJSONDecode(NSData *data, NSError **error) {
|
|||
NSUInteger readOptions = 0;
|
||||
[invocation setArgument:&readOptions atIndex:3];
|
||||
if (error != NULL) {
|
||||
[invocation setArgument:error atIndex:4];
|
||||
[invocation setArgument:&error atIndex:4];
|
||||
}
|
||||
|
||||
[invocation invoke];
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
@interface AFNetworkActivityIndicatorManager : NSObject {
|
||||
@private
|
||||
NSInteger _activityCount;
|
||||
BOOL _enabled;
|
||||
NSTimer *_activityIndicatorVisibilityTimer;
|
||||
}
|
||||
@interface AFNetworkActivityIndicatorManager : NSObject
|
||||
|
||||
/**
|
||||
A Boolean value indicating whether the manager is enabled.
|
||||
|
|
@ -44,6 +39,11 @@
|
|||
*/
|
||||
@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.
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#import "AFNetworkActivityIndicatorManager.h"
|
||||
|
||||
#import "AFHTTPRequestOperation.h"
|
||||
#import <libkern/OSAtomic.h>
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25;
|
||||
|
|
@ -56,7 +57,7 @@ static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25;
|
|||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(incrementActivityCount) name:AFNetworkingOperationDidStartNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(decrementActivityCount) name:AFNetworkingOperationDidFinishNotification object:nil];
|
||||
|
||||
|
|
@ -72,11 +73,7 @@ static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25;
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)setActivityCount:(NSInteger)activityCount {
|
||||
[self willChangeValueForKey:@"activityCount"];
|
||||
_activityCount = MAX(activityCount, 0);
|
||||
[self didChangeValueForKey:@"activityCount"];
|
||||
|
||||
- (void)updateNetworkActivityIndicatorVisibilityDelayed {
|
||||
if (self.enabled) {
|
||||
// Delay hiding of activity indicator for a short interval, to avoid flickering
|
||||
if (![self isNetworkActivityIndicatorVisible]) {
|
||||
|
|
@ -90,23 +87,41 @@ static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25;
|
|||
}
|
||||
|
||||
- (BOOL)isNetworkActivityIndicatorVisible {
|
||||
return self.activityCount > 0;
|
||||
return _activityCount > 0;
|
||||
}
|
||||
|
||||
- (void)updateNetworkActivityIndicatorVisibility {
|
||||
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:[self isNetworkActivityIndicatorVisible]];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[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 {
|
||||
@synchronized(self) {
|
||||
self.activityCount += 1;
|
||||
}
|
||||
[self willChangeValueForKey:@"activityCount"];
|
||||
OSAtomicIncrement32((int32_t*)&_activityCount);
|
||||
[self didChangeValueForKey:@"activityCount"];
|
||||
[self updateNetworkActivityIndicatorVisibilityDelayed];
|
||||
}
|
||||
|
||||
- (void)decrementActivityCount {
|
||||
@synchronized(self) {
|
||||
self.activityCount -= 1;
|
||||
}
|
||||
[self willChangeValueForKey:@"activityCount"];
|
||||
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
|
||||
|
|
|
|||
|
|
@ -178,7 +178,6 @@ Scott Raymond
|
|||
|
||||
- http://github.com/sco
|
||||
- http://twitter.com/sco
|
||||
- sco@gowalla.com
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
|||
|
|
@ -42,8 +42,10 @@
|
|||
self.navigationItem.rightBarButtonItem.enabled = NO;
|
||||
|
||||
[Tweet publicTimelineTweetsWithBlock:^(NSArray *tweets) {
|
||||
_tweets = tweets;
|
||||
[self.tableView reloadData];
|
||||
if (tweets) {
|
||||
_tweets = tweets;
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
[_activityIndicatorView stopAnimating];
|
||||
self.navigationItem.rightBarButtonItem.enabled = YES;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,12 @@
|
|||
}
|
||||
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
|
||||
NSLog(@"Error: %@", error);
|
||||
|
||||
[[[UIAlertView alloc] initWithTitle:@"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Ok", nil] show];
|
||||
|
||||
if (block) {
|
||||
block(nil);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue