Merge branch 'master' into experimental-pause-resume

Conflicts:
	AFNetworking/AFHTTPRequestOperation.h
	AFNetworking/AFURLConnectionOperation.h
This commit is contained in:
Mattt Thompson 2012-04-08 15:28:58 -07:00
commit da1acf5a56
17 changed files with 95 additions and 129 deletions

View file

@ -125,15 +125,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

View file

@ -125,7 +125,8 @@ NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSStringEn
@property (readwrite, nonatomic, retain) id key; @property (readwrite, nonatomic, retain) id key;
@property (readwrite, nonatomic, retain) id value; @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 @end
@ -133,7 +134,7 @@ NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSStringEn
@synthesize key = _key; @synthesize key = _key;
@synthesize value = _value; @synthesize value = _value;
- (id)initWithKey:(NSString *)key value:(NSString *)value { - (id)initWithKey:(id)key value:(id)value {
self = [super init]; self = [super init];
if (!self) { if (!self) {
return nil; return nil;
@ -151,55 +152,56 @@ NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSStringEn
[super dealloc]; [super dealloc];
} }
- (NSString *)description { - (NSString *)URLEncodedStringValueWithEncoding:(NSStringEncoding)stringEncoding {
return [NSString stringWithFormat:@"%@=%@", self.key, self.value]; return [NSString stringWithFormat:@"%@=%@", self.key, AFURLEncodedStringFromStringWithEncoding([self.value description], stringEncoding)];
} }
@end @end
#pragma mark - #pragma mark -
extern NSArray * AFQueryStringComponentsFromKeyAndValueWithEncoding(NSString *key, id value, NSStringEncoding stringEncoding); extern NSArray * AFQueryStringComponentsFromKeyAndValue(NSString *key, id value);
extern NSArray * AFQueryStringComponentsFromKeyAndDictionaryValueWithEncoding(NSString *key, NSDictionary *value, NSStringEncoding stringEncoding); extern NSArray * AFQueryStringComponentsFromKeyAndDictionaryValue(NSString *key, NSDictionary *value);
extern NSArray * AFQueryStringComponentsFromKeyAndArrayValueWithEncoding(NSString *key, NSArray *value, NSStringEncoding stringEncoding); extern NSArray * AFQueryStringComponentsFromKeyAndArrayValue(NSString *key, NSArray *value);
NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *parameters, NSStringEncoding stringEncoding) { NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *parameters, NSStringEncoding stringEncoding) {
return [[AFQueryStringComponentsFromKeyAndValueWithEncoding(nil, parameters, stringEncoding) valueForKeyPath:@"description"] componentsJoinedByString:@"&"]; 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) { NSArray * AFQueryStringComponentsFromKeyAndValue(NSString *key, id value) {
return [[[AFQueryStringComponent alloc] initWithKey:AFURLEncodedStringFromStringWithEncoding([key description], stringEncoding) value:AFURLEncodedStringFromStringWithEncoding([value description], stringEncoding)] autorelease];
}
NSArray * AFQueryStringComponentsFromKeyAndValueWithEncoding(NSString *key, id value, NSStringEncoding stringEncoding) {
NSMutableArray *mutableQueryStringComponents = [NSMutableArray array]; NSMutableArray *mutableQueryStringComponents = [NSMutableArray array];
if([value isKindOfClass:[NSDictionary class]]) { if([value isKindOfClass:[NSDictionary class]]) {
[mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndDictionaryValueWithEncoding(key, value, stringEncoding)]; [mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndDictionaryValue(key, value)];
} else if([value isKindOfClass:[NSArray class]]) { } else if([value isKindOfClass:[NSArray class]]) {
[mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndArrayValueWithEncoding(key, value, stringEncoding)]; [mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndArrayValue(key, value)];
} else { } else {
[mutableQueryStringComponents addObject:AFQueryStringComponentFromKeyAndValueWithEncoding(key, value, stringEncoding)]; [mutableQueryStringComponents addObject:[[[AFQueryStringComponent alloc] initWithKey:key value:value] autorelease]];
} }
return mutableQueryStringComponents; return mutableQueryStringComponents;
} }
NSArray * AFQueryStringComponentsFromKeyAndDictionaryValueWithEncoding(NSString *key, NSDictionary *value, NSStringEncoding stringEncoding){ NSArray * AFQueryStringComponentsFromKeyAndDictionaryValue(NSString *key, NSDictionary *value){
NSMutableArray *mutableQueryStringComponents = [NSMutableArray array]; NSMutableArray *mutableQueryStringComponents = [NSMutableArray array];
[value enumerateKeysAndObjectsUsingBlock:^(id k, id v, BOOL *stop) { [value enumerateKeysAndObjectsUsingBlock:^(id nestedKey, id nestedValue, BOOL *stop) {
[mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndValueWithEncoding((key ? [NSString stringWithFormat:@"%@[%@]", key, k] : k), v, stringEncoding)]; [mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndValue((key ? [NSString stringWithFormat:@"%@[%@]", key, nestedKey] : nestedKey), nestedValue)];
}]; }];
return mutableQueryStringComponents; return mutableQueryStringComponents;
} }
NSArray * AFQueryStringComponentsFromKeyAndArrayValueWithEncoding(NSString *key, NSArray *value, NSStringEncoding stringEncoding) { NSArray * AFQueryStringComponentsFromKeyAndArrayValue(NSString *key, NSArray *value) {
NSMutableArray *mutableQueryStringComponents = [NSMutableArray array]; NSMutableArray *mutableQueryStringComponents = [NSMutableArray array];
[value enumerateObjectsUsingBlock:^(id v, NSUInteger idx, BOOL *stop) { [value enumerateObjectsUsingBlock:^(id nestedValue, NSUInteger idx, BOOL *stop) {
[mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndValueWithEncoding([NSString stringWithFormat:@"%@[]", key], v, stringEncoding)]; [mutableQueryStringComponents addObjectsFromArray:AFQueryStringComponentsFromKeyAndValue([NSString stringWithFormat:@"%@[]", key], nestedValue)];
}]; }];
return mutableQueryStringComponents; return mutableQueryStringComponents;
@ -496,8 +498,15 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
NSMutableURLRequest *request = [self requestWithMethod:method path:path parameters:nil]; NSMutableURLRequest *request = [self requestWithMethod:method path:path parameters:nil];
__block AFMultipartFormData *formData = [[AFMultipartFormData alloc] initWithStringEncoding:self.stringEncoding]; __block AFMultipartFormData *formData = [[AFMultipartFormData alloc] initWithStringEncoding:self.stringEncoding];
for (AFQueryStringComponent *component in AFQueryStringComponentsFromKeyAndValueWithEncoding(nil, parameters, self.stringEncoding)) { for (AFQueryStringComponent *component in AFQueryStringComponentsFromKeyAndValue(nil, parameters)) {
[formData appendPartWithFormData:[component.value dataUsingEncoding:self.stringEncoding] name:component.key]; 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) { if (block) {

View file

@ -31,12 +31,7 @@ extern NSSet * AFContentTypesFromHTTPHeader(NSString *string);
/** /**
`AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request. `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
NSError *_HTTPError;
dispatch_queue_t _successCallbackQueue;
dispatch_queue_t _failureCallbackQueue;
}
///---------------------------------------------- ///----------------------------------------------
/// @name Getting HTTP URL Connection Information /// @name Getting HTTP URL Connection Information

View file

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

View file

@ -157,9 +157,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;
} }

View file

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

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

View file

@ -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;
@ -56,7 +57,7 @@ static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.25;
if (!self) { if (!self) {
return nil; return nil;
} }
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(incrementActivityCount) name:AFNetworkingOperationDidStartNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(incrementActivityCount) name:AFNetworkingOperationDidStartNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(decrementActivityCount) name:AFNetworkingOperationDidFinishNotification 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]; [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 {
[[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 { - (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

View file

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

View file

@ -75,23 +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 <NSURLConnectionDataDelegate> { @interface AFURLConnectionOperation : NSOperation
@private
signed short _state;
BOOL _cancelled;
NSRecursiveLock *_lock;
NSSet *_runLoopModes;
NSURLConnection *_connection;
NSURLRequest *_request;
NSHTTPURLResponse *_response;
NSError *_error;
NSData *_responseData;
long long _totalBytesRead;
NSOutputStream *_outputStream;
}
///------------------------------- ///-------------------------------
/// @name Accessing Run Loop Modes /// @name Accessing Run Loop Modes

View file

@ -89,6 +89,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;
@ -109,6 +110,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;
@ -351,10 +353,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;
} }

View file

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

View file

@ -28,8 +28,8 @@
@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
#pragma mark - #pragma mark -
@ -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)cacheImageData:(NSData *)imageData - (void)cacheImage:(UIImage *)image
forRequest:(NSURLRequest *)request forRequest:(NSURLRequest *)request
{ {
[self setObject:[NSPurgeableData dataWithData:imageData] forKey:AFImageCacheKeyFromURLRequest(request)]; [self setObject:image forKey:AFImageCacheKeyFromURLRequest(request)];
} }
@end @end

View file

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

View file

@ -42,8 +42,10 @@
self.navigationItem.rightBarButtonItem.enabled = NO; self.navigationItem.rightBarButtonItem.enabled = NO;
[Tweet publicTimelineTweetsWithBlock:^(NSArray *tweets) { [Tweet publicTimelineTweetsWithBlock:^(NSArray *tweets) {
_tweets = tweets; if (tweets) {
[self.tableView reloadData]; _tweets = tweets;
[self.tableView reloadData];
}
[_activityIndicatorView stopAnimating]; [_activityIndicatorView stopAnimating];
self.navigationItem.rightBarButtonItem.enabled = YES; self.navigationItem.rightBarButtonItem.enabled = YES;

View file

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

View file

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