Merge branch 'master' into experimental-1.0RC1

This commit is contained in:
Mattt Thompson 2012-04-08 12:35:47 -07:00
commit 9e73238a7b
7 changed files with 106 additions and 68 deletions

View file

@ -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) {

View file

@ -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];

View file

@ -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.

View file

@ -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

View file

@ -178,7 +178,6 @@ Scott Raymond
- http://github.com/sco
- http://twitter.com/sco
- sco@gowalla.com
## License

View file

@ -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;

View file

@ -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);
}
}];
}