Merge branch 'experimental-0.9'
This commit is contained in:
commit
1c64c6c374
22 changed files with 601 additions and 453 deletions
|
|
@ -1,11 +1,12 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = 'AFNetworking'
|
||||
s.version = '0.8.0'
|
||||
s.version = '0.9.0'
|
||||
s.license = 'MIT'
|
||||
s.summary = 'A delightful iOS and OS X networking framework'
|
||||
s.homepage = 'https://github.com/AFNetworking/AFNetworking'
|
||||
s.authors = {'Mattt Thompson' => 'm@mattt.me', 'Scott Raymond' => 'sco@gowalla.com'}
|
||||
s.source = { :git => 'https://github.com/AFNetworking/AFNetworking.git',
|
||||
:tag => '0.8.0' }
|
||||
|
||||
s.source = { :git => 'https://github.com/AFNetworking/AFNetworking.git', :tag => '0.9.0' }
|
||||
s.source_files = 'AFNetworking'
|
||||
s.clean_paths = ['iOS Example', 'Mac Example', 'AFNetworking.xcworkspace']
|
||||
s.framework = 'SystemConfiguration'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -160,9 +160,24 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete
|
|||
*/
|
||||
- (id)initWithBaseURL:(NSURL *)url;
|
||||
|
||||
///----------------------------------
|
||||
///-----------------------------------
|
||||
/// @name Managing Reachability Status
|
||||
///-----------------------------------
|
||||
|
||||
/**
|
||||
Sets a callback to be executed when the network availability of the `baseURL` host changes.
|
||||
|
||||
@param block A block object to be executed when the network availability of the `baseURL` host changes.. This block has no return value and takes a single argument, which is `YES` if the host is available, otherwise `NO`.
|
||||
|
||||
@warning This method requires the `SystemConfiguration` framework. Add it in the active target's "Link Binary With Library" build phase, and add `#import <SystemConfiguration/SystemConfiguration.h>` to the header prefix of the project (Prefix.pch).
|
||||
*/
|
||||
#ifdef _SYSTEMCONFIGURATION_H
|
||||
- (void)setReachabilityStatusChangeBlock:(void (^)(BOOL isNetworkReachable))block;
|
||||
#endif
|
||||
|
||||
///-------------------------------
|
||||
/// @name Managing HTTP Operations
|
||||
///----------------------------------
|
||||
///-------------------------------
|
||||
|
||||
/**
|
||||
Attempts to register a subclass of `AFHTTPRequestOperation`, adding it to a chain to automatically generate request operations from a URL request.
|
||||
|
|
@ -294,12 +309,40 @@ extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *paramete
|
|||
- (void)enqueueHTTPRequestOperation:(AFHTTPRequestOperation *)operation;
|
||||
|
||||
/**
|
||||
Cancels all operations in the HTTP client's operation queue that match the specified HTTP method and URL.
|
||||
Cancels all operations in the HTTP client's operation queue whose URLs match the specified HTTP method and path.
|
||||
|
||||
@param method The HTTP method to match for the cancelled requests, such as `GET`, `POST`, `PUT`, or `DELETE`.
|
||||
@param url The URL to match for the cancelled requests.
|
||||
@param method The HTTP method to match for the cancelled requests, such as `GET`, `POST`, `PUT`, or `DELETE`. If `nil`, all request operations with URLs matching the path will be cancelled.
|
||||
@param url The path to match for the cancelled requests.
|
||||
*/
|
||||
- (void)cancelHTTPOperationsWithMethod:(NSString *)method andURL:(NSURL *)url;
|
||||
- (void)cancelAllHTTPOperationsWithMethod:(NSString *)method path:(NSString *)path;
|
||||
|
||||
///---------------------------------------
|
||||
/// @name Batching HTTP Request Operations
|
||||
///---------------------------------------
|
||||
|
||||
/**
|
||||
Creates and enqueues an `AFHTTPRequestOperation` to the HTTP client's operation queue for each specified request object into a batch. When each request operation finishes, the specified progress block is executed, until all of the request operations have finished, at which point the completion block also executes.
|
||||
|
||||
@param requests The `NSURLRequest` objects used to create and enqueue operations.
|
||||
@param progressBlock A block object to be executed upon the completion of each request operation in the batch. This block has no return value and takes two arguments: the number of operations that have already finished execution, and the total number of operations.
|
||||
@param completionBlock A block object to be executed upon the completion of all of the request operations in the batch. This block has no return value and takes a single argument: the batched request operations.
|
||||
|
||||
@discussion Operations are created by passing the specified `NSURLRequest` objects in `requests`, using `-HTTPRequestOperationWithRequest:success:failure:`, with `nil` for both the `success` and `failure` parameters.
|
||||
*/
|
||||
- (void)enqueueBatchOfHTTPRequestOperationsWithRequests:(NSArray *)requests
|
||||
progressBlock:(void (^)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations))progressBlock
|
||||
completionBlock:(void (^)(NSArray *operations))completionBlock;
|
||||
|
||||
/**
|
||||
Enqueues the specified request operations into a batch. When each request operation finishes, the specified progress block is executed, until all of the request operations have finished, at which point the completion block also executes.
|
||||
|
||||
@param operations The request operations used to be batched and enqueued.
|
||||
@param progressBlock A block object to be executed upon the completion of each request operation in the batch. This block has no return value and takes two arguments: the number of operations that have already finished execution, and the total number of operations.
|
||||
@param completionBlock A block object to be executed upon the completion of all of the request operations in the batch. This block has no return value and takes a single argument: the batched request operations.
|
||||
*/
|
||||
- (void)enqueueBatchOfHTTPRequestOperations:(NSArray *)operations
|
||||
progressBlock:(void (^)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations))progressBlock
|
||||
completionBlock:(void (^)(NSArray *operations))completionBlock;
|
||||
|
||||
///---------------------------
|
||||
/// @name Making HTTP Requests
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@
|
|||
#import <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
#ifdef _SYSTEMCONFIGURATION_H
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
#endif
|
||||
|
||||
static NSString * const kAFMultipartFormLineDelimiter = @"\r\n"; // CRLF
|
||||
static NSString * const kAFMultipartFormBoundary = @"Boundary+0xAbCdEfGbOuNdArY";
|
||||
|
||||
@interface AFMultipartFormData : NSObject <AFMultipartFormData> {
|
||||
|
|
@ -48,6 +53,15 @@ static NSString * const kAFMultipartFormBoundary = @"Boundary+0xAbCdEfGbOuNdArY"
|
|||
|
||||
#pragma mark -
|
||||
|
||||
#ifdef _SYSTEMCONFIGURATION_H
|
||||
typedef SCNetworkReachabilityRef AFNetworkReachabilityRef;
|
||||
#else
|
||||
typedef id AFNetworkReachabilityRef;
|
||||
#endif
|
||||
|
||||
typedef void (^AFNetworkReachabilityStatusBlock)(BOOL isNetworkReachable);
|
||||
typedef void (^AFCompletionBlock)(void);
|
||||
|
||||
static NSUInteger const kAFHTTPClientDefaultMaxConcurrentOperationCount = 4;
|
||||
|
||||
static NSString * AFBase64EncodedStringFromString(NSString *string) {
|
||||
|
|
@ -132,6 +146,8 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
|
|||
@property (readwrite, nonatomic, retain) NSMutableArray *registeredHTTPOperationClassNames;
|
||||
@property (readwrite, nonatomic, retain) NSMutableDictionary *defaultHeaders;
|
||||
@property (readwrite, nonatomic, retain) NSOperationQueue *operationQueue;
|
||||
@property (readwrite, nonatomic, assign) AFNetworkReachabilityRef networkReachability;
|
||||
@property (readwrite, nonatomic, copy) AFNetworkReachabilityStatusBlock networkReachabilityStatusBlock;
|
||||
@end
|
||||
|
||||
@implementation AFHTTPClient
|
||||
|
|
@ -141,6 +157,8 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
|
|||
@synthesize registeredHTTPOperationClassNames = _registeredHTTPOperationClassNames;
|
||||
@synthesize defaultHeaders = _defaultHeaders;
|
||||
@synthesize operationQueue = _operationQueue;
|
||||
@synthesize networkReachability = _networkReachability;
|
||||
@synthesize networkReachabilityStatusBlock = _networkReachabilityStatusBlock;
|
||||
|
||||
+ (AFHTTPClient *)clientWithBaseURL:(NSURL *)url {
|
||||
return [[[self alloc] initWithBaseURL:url] autorelease];
|
||||
|
|
@ -186,9 +204,43 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
|
|||
[_registeredHTTPOperationClassNames release];
|
||||
[_defaultHeaders release];
|
||||
[_operationQueue release];
|
||||
[_networkReachabilityStatusBlock release];
|
||||
if (_networkReachability) {
|
||||
CFRelease(_networkReachability);
|
||||
}
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, defaultHeaders: %@, registeredOperationClasses: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.defaultHeaders, self.registeredHTTPOperationClassNames, self.operationQueue];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
#ifdef _SYSTEMCONFIGURATION_H
|
||||
static void AFReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) {
|
||||
if (info) {
|
||||
AFNetworkReachabilityStatusBlock block = (AFNetworkReachabilityStatusBlock)info;
|
||||
BOOL isNetworkReachable = (flags & kSCNetworkReachabilityFlagsReachable);
|
||||
block(isNetworkReachable);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setReachabilityStatusChangeBlock:(void (^)(BOOL isNetworkReachable))block {
|
||||
if (_networkReachability) {
|
||||
SCNetworkReachabilityUnscheduleFromRunLoop(_networkReachability, CFRunLoopGetMain(), (CFStringRef)NSRunLoopCommonModes);
|
||||
CFRelease(_networkReachability);
|
||||
}
|
||||
|
||||
self.networkReachabilityStatusBlock = block;
|
||||
self.networkReachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [[self.baseURL host] UTF8String]);
|
||||
SCNetworkReachabilityContext context = {0, self.networkReachabilityStatusBlock, NULL, NULL, NULL};
|
||||
SCNetworkReachabilitySetCallback(self.networkReachability, AFReachabilityCallback, &context);
|
||||
SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), (CFStringRef)NSRunLoopCommonModes);
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (BOOL)registerHTTPOperationClass:(Class)operationClass {
|
||||
|
|
@ -326,18 +378,64 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
|
|||
return operation;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)enqueueHTTPRequestOperation:(AFHTTPRequestOperation *)operation {
|
||||
[self.operationQueue addOperation:operation];
|
||||
}
|
||||
|
||||
- (void)cancelHTTPOperationsWithMethod:(NSString *)method andURL:(NSURL *)url {
|
||||
- (void)cancelAllHTTPOperationsWithMethod:(NSString *)method path:(NSString *)path {
|
||||
for (AFHTTPRequestOperation *operation in [self.operationQueue operations]) {
|
||||
if ([[[operation request] HTTPMethod] isEqualToString:method] && [[[operation request] URL] isEqual:url]) {
|
||||
if ((!method || [method isEqualToString:[[operation request] HTTPMethod]]) && [path isEqualToString:[[[operation request] URL] path]]) {
|
||||
[operation cancel];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)enqueueBatchOfHTTPRequestOperationsWithRequests:(NSArray *)requests
|
||||
progressBlock:(void (^)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations))progressBlock
|
||||
completionBlock:(void (^)(NSArray *operations))completionBlock
|
||||
{
|
||||
NSMutableArray *mutableOperations = [NSMutableArray array];
|
||||
for (NSURLRequest *request in requests) {
|
||||
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:nil failure:nil];
|
||||
[mutableOperations addObject:operation];
|
||||
}
|
||||
|
||||
[self enqueueBatchOfHTTPRequestOperations:mutableOperations progressBlock:progressBlock completionBlock:completionBlock];
|
||||
}
|
||||
|
||||
- (void)enqueueBatchOfHTTPRequestOperations:(NSArray *)operations
|
||||
progressBlock:(void (^)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations))progressBlock
|
||||
completionBlock:(void (^)(NSArray *operations))completionBlock
|
||||
{
|
||||
NSBlockOperation *batchedOperation = [NSBlockOperation blockOperationWithBlock:^{
|
||||
if (completionBlock) {
|
||||
completionBlock(operations);
|
||||
}
|
||||
}];
|
||||
|
||||
[self.operationQueue addOperation:batchedOperation];
|
||||
|
||||
NSPredicate *finishedOperationPredicate = [NSPredicate predicateWithFormat:@"isFinished == YES"];
|
||||
|
||||
for (AFHTTPRequestOperation *operation in operations) {
|
||||
AFCompletionBlock originalCompletionBlock = [[operation.completionBlock copy] autorelease];
|
||||
operation.completionBlock = ^{
|
||||
if (progressBlock) {
|
||||
progressBlock([[batchedOperation.dependencies filteredArrayUsingPredicate:finishedOperationPredicate] count], [batchedOperation.dependencies count]);
|
||||
}
|
||||
|
||||
if (originalCompletionBlock) {
|
||||
originalCompletionBlock();
|
||||
}
|
||||
};
|
||||
|
||||
[batchedOperation addDependency:operation];
|
||||
[self enqueueHTTPRequestOperation:operation];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)getPath:(NSString *)path
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
@interface AFHTTPRequestOperation ()
|
||||
@property (readwrite, nonatomic, retain) NSError *HTTPError;
|
||||
@property (readonly, nonatomic, assign) BOOL hasContent;
|
||||
@end
|
||||
|
||||
@implementation AFHTTPRequestOperation
|
||||
|
|
@ -62,7 +61,7 @@
|
|||
[userInfo setValue:[self.request URL] forKey:NSURLErrorFailingURLErrorKey];
|
||||
|
||||
self.HTTPError = [[[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadServerResponse userInfo:userInfo] autorelease];
|
||||
} else if ([self hasContent] && ![self hasAcceptableContentType]) { // Don't invalidate content type if there is no content
|
||||
} 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.acceptableContentTypes, [self.response MIMEType]] forKey:NSLocalizedDescriptionKey];
|
||||
[userInfo setValue:[self.request URL] forKey:NSURLErrorFailingURLErrorKey];
|
||||
|
|
@ -71,17 +70,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
if (_HTTPError) {
|
||||
return _HTTPError;
|
||||
if (self.HTTPError) {
|
||||
return self.HTTPError;
|
||||
} else {
|
||||
return [super error];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)hasContent {
|
||||
return [self.responseData length] > 0;
|
||||
}
|
||||
|
||||
- (BOOL)hasAcceptableStatusCode {
|
||||
return !self.acceptableStatusCodes || [self.acceptableStatusCodes containsIndex:[self.response statusCode]];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
// AFImageCache.h
|
||||
//
|
||||
// Copyright (c) 2011 Gowalla (http://gowalla.com/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "AFImageRequestOperation.h"
|
||||
|
||||
#import <Availability.h>
|
||||
|
||||
/**
|
||||
`AFImageCache` is an `NSCache` that stores and retrieves images from cache.
|
||||
|
||||
@discussion `AFImageCache` is used to cache images for successful `AFImageRequestOperations` with the proper cache policy.
|
||||
*/
|
||||
@interface AFImageCache : NSCache
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
/**
|
||||
The scale factor used when interpreting the cached image data. Specifying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the size property. This is set to the value of `[[UIScreen mainScreen] scale]` by default, which automatically scales images for retina displays, for instance.
|
||||
*/
|
||||
@property (nonatomic, assign) CGFloat imageScale;
|
||||
#endif
|
||||
|
||||
/**
|
||||
Returns the shared image cache object for the system.
|
||||
|
||||
@return The systemwide image cache.
|
||||
*/
|
||||
+ (AFImageCache *)sharedImageCache;
|
||||
|
||||
/**
|
||||
Returns the image associated with a given URL and cache name.
|
||||
|
||||
@param url The URL associated with the image in the cache.
|
||||
@param cacheName The cache name associated with the image in the cache. This allows for multiple versions of an image to be associated for a single URL, such as image thumbnails, for instance.
|
||||
|
||||
@return The image associated with the URL and cache name, or `nil` if not image exists.
|
||||
*/
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
- (UIImage *)cachedImageForURL:(NSURL *)url
|
||||
cacheName:(NSString *)cacheName;
|
||||
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
- (NSImage *)cachedImageForURL:(NSURL *)url
|
||||
cacheName:(NSString *)cacheName;
|
||||
#endif
|
||||
|
||||
/**
|
||||
Stores image data into cache, associated with a given URL and cache name.
|
||||
|
||||
@param imageData The image data to be stored in cache.
|
||||
@param url The URL to be associated with the image.
|
||||
@param cacheName The cache name to be associated with the image in the cache. This allows for multiple versions of an image to be associated for a single URL, such as image thumbnails, for instance.
|
||||
*/
|
||||
- (void)cacheImageData:(NSData *)imageData
|
||||
forURL:(NSURL *)url
|
||||
cacheName:(NSString *)cacheName;
|
||||
|
||||
@end
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
// AFImageCache.m
|
||||
//
|
||||
// Copyright (c) 2011 Gowalla (http://gowalla.com/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "AFImageCache.h"
|
||||
|
||||
static inline NSString * AFImageCacheKeyFromURLAndCacheName(NSURL *url, NSString *cacheName) {
|
||||
return [[url absoluteString] stringByAppendingFormat:@"#%@", cacheName];
|
||||
}
|
||||
|
||||
@implementation AFImageCache
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
@synthesize imageScale = _imageScale;
|
||||
#endif
|
||||
|
||||
+ (AFImageCache *)sharedImageCache {
|
||||
static AFImageCache *_sharedImageCache = nil;
|
||||
static dispatch_once_t oncePredicate;
|
||||
dispatch_once(&oncePredicate, ^{
|
||||
_sharedImageCache = [[self alloc] init];
|
||||
});
|
||||
|
||||
return _sharedImageCache;
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
self.imageScale = [[UIScreen mainScreen] scale];
|
||||
#endif
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
- (UIImage *)cachedImageForURL:(NSURL *)url
|
||||
cacheName:(NSString *)cacheName
|
||||
{
|
||||
UIImage *image = [UIImage imageWithData:[self objectForKey:AFImageCacheKeyFromURLAndCacheName(url, cacheName)]];
|
||||
if (image) {
|
||||
return [UIImage imageWithCGImage:[image CGImage] scale:self.imageScale orientation:image.imageOrientation];
|
||||
}
|
||||
return image;
|
||||
}
|
||||
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
- (NSImage *)cachedImageForURL:(NSURL *)url
|
||||
cacheName:(NSString *)cacheName
|
||||
{
|
||||
return [[[NSImage alloc] initWithData:[self objectForKey:AFImageCacheKeyFromURLAndCacheName(url, cacheName)]] autorelease];
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)cacheImageData:(NSData *)imageData
|
||||
forURL:(NSURL *)url
|
||||
cacheName:(NSString *)cacheName
|
||||
{
|
||||
[self setObject:[NSPurgeableData dataWithData:imageData] forKey:AFImageCacheKeyFromURLAndCacheName(url, cacheName)];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -21,7 +21,6 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#import "AFImageRequestOperation.h"
|
||||
#import "AFImageCache.h"
|
||||
|
||||
static dispatch_queue_t af_image_request_operation_processing_queue;
|
||||
static dispatch_queue_t image_request_operation_processing_queue() {
|
||||
|
|
@ -157,7 +156,7 @@ static dispatch_queue_t image_request_operation_processing_queue() {
|
|||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
- (UIImage *)responseImage {
|
||||
if (!_responseImage && [self isFinished]) {
|
||||
if (!_responseImage && [self.responseData length] > 0 && [self isFinished]) {
|
||||
UIImage *image = [UIImage imageWithData:self.responseData];
|
||||
|
||||
self.responseImage = [UIImage imageWithCGImage:[image CGImage] scale:self.imageScale orientation:image.imageOrientation];
|
||||
|
|
@ -179,7 +178,7 @@ static dispatch_queue_t image_request_operation_processing_queue() {
|
|||
}
|
||||
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
- (NSImage *)responseImage {
|
||||
if (!_responseImage && [self isFinished]) {
|
||||
if (!_responseImage && [self.responseData length] > 0 && [self isFinished]) {
|
||||
// Ensure that the image is set to it's correct pixel width and height
|
||||
NSBitmapImageRep *bitimage = [[NSBitmapImageRep alloc] initWithData:self.responseData];
|
||||
self.responseImage = [[[NSImage alloc] initWithSize:NSMakeSize([bitimage pixelsWide], [bitimage pixelsHigh])] autorelease];
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ static dispatch_queue_t json_request_operation_processing_queue() {
|
|||
}
|
||||
|
||||
- (id)responseJSON {
|
||||
if (!_responseJSON && [self isFinished]) {
|
||||
if (!_responseJSON && [self.responseData length] > 0 && [self isFinished]) {
|
||||
NSError *error = nil;
|
||||
|
||||
if ([self.responseData length] == 0) {
|
||||
|
|
|
|||
|
|
@ -22,148 +22,5 @@
|
|||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
static NSData * AFJSONEncode(id object, NSError **error) {
|
||||
NSData *data = nil;
|
||||
|
||||
SEL _JSONKitSelector = NSSelectorFromString(@"JSONDataWithOptions:error:");
|
||||
SEL _SBJSONSelector = NSSelectorFromString(@"JSONRepresentation");
|
||||
SEL _YAJLSelector = NSSelectorFromString(@"yajl_JSONString");
|
||||
|
||||
id _NSJSONSerializationClass = NSClassFromString(@"NSJSONSerialization");
|
||||
SEL _NSJSONSerializationSelector = NSSelectorFromString(@"dataWithJSONObject:options:error:");
|
||||
|
||||
#ifdef _AFNETWORKING_PREFER_NSJSONSERIALIZATION_
|
||||
if (_NSJSONSerializationClass && [_NSJSONSerializationClass respondsToSelector:_NSJSONSerializationSelector]) {
|
||||
goto _af_nsjson_encode;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_JSONKitSelector && [object respondsToSelector:_JSONKitSelector]) {
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[object methodSignatureForSelector:_JSONKitSelector]];
|
||||
invocation.target = object;
|
||||
invocation.selector = _JSONKitSelector;
|
||||
|
||||
NSUInteger serializeOptionFlags = 0;
|
||||
[invocation setArgument:&serializeOptionFlags atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
[invocation setArgument:error atIndex:3];
|
||||
|
||||
[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;
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&JSONString];
|
||||
|
||||
data = [JSONString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
} else if (_YAJLSelector && [object respondsToSelector:_YAJLSelector]) {
|
||||
@try {
|
||||
NSString *JSONString = nil;
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[object methodSignatureForSelector:_YAJLSelector]];
|
||||
invocation.target = object;
|
||||
invocation.selector = _YAJLSelector;
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&JSONString];
|
||||
|
||||
data = [JSONString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
*error = [[[NSError alloc] initWithDomain:NSStringFromClass([exception class]) code:0 userInfo:[exception userInfo]] autorelease];
|
||||
}
|
||||
} else if (_NSJSONSerializationClass && [_NSJSONSerializationClass respondsToSelector:_NSJSONSerializationSelector]) {
|
||||
#ifdef _AFNETWORKING_PREFER_NSJSONSERIALIZATION_
|
||||
_af_nsjson_encode:
|
||||
#endif
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[_NSJSONSerializationClass methodSignatureForSelector:_NSJSONSerializationSelector]];
|
||||
invocation.target = _NSJSONSerializationClass;
|
||||
invocation.selector = _NSJSONSerializationSelector;
|
||||
|
||||
[invocation setArgument:&object atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
NSUInteger writeOptions = 0;
|
||||
[invocation setArgument:&writeOptions atIndex:3];
|
||||
[invocation setArgument:error atIndex:4];
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&data];
|
||||
} else {
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:NSLocalizedString(@"Please either target a platform that supports NSJSONSerialization or add one of the following libraries to your project: JSONKit, SBJSON, or YAJL", nil) forKey:NSLocalizedRecoverySuggestionErrorKey];
|
||||
[[NSException exceptionWithName:NSInternalInconsistencyException reason:NSLocalizedString(@"No JSON generation functionality available", nil) userInfo:userInfo] raise];
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static 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 _NSJSONSerializationClass = NSClassFromString(@"NSJSONSerialization");
|
||||
SEL _NSJSONSerializationSelector = NSSelectorFromString(@"JSONObjectWithData:options:error:");
|
||||
|
||||
|
||||
#ifdef _AFNETWORKING_PREFER_NSJSONSERIALIZATION_
|
||||
if (_NSJSONSerializationClass && [_NSJSONSerializationClass respondsToSelector:_NSJSONSerializationSelector]) {
|
||||
goto _af_nsjson_decode;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_JSONKitSelector && [data respondsToSelector:_JSONKitSelector]) {
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[data methodSignatureForSelector:_JSONKitSelector]];
|
||||
invocation.target = data;
|
||||
invocation.selector = _JSONKitSelector;
|
||||
|
||||
NSUInteger parseOptionFlags = 0;
|
||||
[invocation setArgument:&parseOptionFlags atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
[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;
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&JSON];
|
||||
} else if (_YAJLSelector && [data respondsToSelector:_YAJLSelector]) {
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[data methodSignatureForSelector:_YAJLSelector]];
|
||||
invocation.target = data;
|
||||
invocation.selector = _YAJLSelector;
|
||||
|
||||
NSUInteger yajlParserOptions = 0;
|
||||
[invocation setArgument:&yajlParserOptions atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
[invocation setArgument:error atIndex:3];
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&JSON];
|
||||
} else if (_NSJSONSerializationClass && [_NSJSONSerializationClass respondsToSelector:_NSJSONSerializationSelector]) {
|
||||
#ifdef _AFNETWORKING_PREFER_NSJSONSERIALIZATION_
|
||||
_af_nsjson_decode:
|
||||
#endif
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[_NSJSONSerializationClass methodSignatureForSelector:_NSJSONSerializationSelector]];
|
||||
invocation.target = _NSJSONSerializationClass;
|
||||
invocation.selector = _NSJSONSerializationSelector;
|
||||
|
||||
[invocation setArgument:&data atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
NSUInteger readOptions = 0;
|
||||
[invocation setArgument:&readOptions atIndex:3];
|
||||
[invocation setArgument:error atIndex:4];
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&JSON];
|
||||
} else {
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:NSLocalizedString(@"Please either target a platform that supports NSJSONSerialization or add one of the following libraries to your project: JSONKit, SBJSON, or YAJL", nil) forKey:NSLocalizedRecoverySuggestionErrorKey];
|
||||
[[NSException exceptionWithName:NSInternalInconsistencyException reason:NSLocalizedString(@"No JSON parsing functionality available", nil) userInfo:userInfo] raise];
|
||||
}
|
||||
|
||||
return JSON;
|
||||
}
|
||||
extern NSData * AFJSONEncode(id object, NSError **error);
|
||||
extern id AFJSONDecode(NSData *data, NSError **error);
|
||||
|
|
|
|||
169
AFNetworking/AFJSONUtilities.m
Normal file
169
AFNetworking/AFJSONUtilities.m
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
// AFJSONUtilities.m
|
||||
//
|
||||
// Copyright (c) 2011 Gowalla (http://gowalla.com/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "AFJSONUtilities.h"
|
||||
|
||||
NSData * AFJSONEncode(id object, NSError **error) {
|
||||
NSData *data = nil;
|
||||
|
||||
SEL _JSONKitSelector = NSSelectorFromString(@"JSONDataWithOptions:error:");
|
||||
SEL _SBJSONSelector = NSSelectorFromString(@"JSONRepresentation");
|
||||
SEL _YAJLSelector = NSSelectorFromString(@"yajl_JSONString");
|
||||
|
||||
id _NSJSONSerializationClass = NSClassFromString(@"NSJSONSerialization");
|
||||
SEL _NSJSONSerializationSelector = NSSelectorFromString(@"dataWithJSONObject:options:error:");
|
||||
|
||||
#ifdef _AFNETWORKING_PREFER_NSJSONSERIALIZATION_
|
||||
if (_NSJSONSerializationClass && [_NSJSONSerializationClass respondsToSelector:_NSJSONSerializationSelector]) {
|
||||
goto _af_nsjson_encode;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_JSONKitSelector && [object respondsToSelector:_JSONKitSelector]) {
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[object methodSignatureForSelector:_JSONKitSelector]];
|
||||
invocation.target = object;
|
||||
invocation.selector = _JSONKitSelector;
|
||||
|
||||
NSUInteger serializeOptionFlags = 0;
|
||||
[invocation setArgument:&serializeOptionFlags atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
[invocation setArgument:error atIndex:3];
|
||||
|
||||
[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;
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&JSONString];
|
||||
|
||||
data = [JSONString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
} else if (_YAJLSelector && [object respondsToSelector:_YAJLSelector]) {
|
||||
@try {
|
||||
NSString *JSONString = nil;
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[object methodSignatureForSelector:_YAJLSelector]];
|
||||
invocation.target = object;
|
||||
invocation.selector = _YAJLSelector;
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&JSONString];
|
||||
|
||||
data = [JSONString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
*error = [[[NSError alloc] initWithDomain:NSStringFromClass([exception class]) code:0 userInfo:[exception userInfo]] autorelease];
|
||||
}
|
||||
} else if (_NSJSONSerializationClass && [_NSJSONSerializationClass respondsToSelector:_NSJSONSerializationSelector]) {
|
||||
#ifdef _AFNETWORKING_PREFER_NSJSONSERIALIZATION_
|
||||
_af_nsjson_encode:
|
||||
#endif
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[_NSJSONSerializationClass methodSignatureForSelector:_NSJSONSerializationSelector]];
|
||||
invocation.target = _NSJSONSerializationClass;
|
||||
invocation.selector = _NSJSONSerializationSelector;
|
||||
|
||||
[invocation setArgument:&object atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
NSUInteger writeOptions = 0;
|
||||
[invocation setArgument:&writeOptions atIndex:3];
|
||||
[invocation setArgument:error atIndex:4];
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&data];
|
||||
} else {
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:NSLocalizedString(@"Please either target a platform that supports NSJSONSerialization or add one of the following libraries to your project: JSONKit, SBJSON, or YAJL", nil) forKey:NSLocalizedRecoverySuggestionErrorKey];
|
||||
[[NSException exceptionWithName:NSInternalInconsistencyException reason:NSLocalizedString(@"No JSON generation functionality available", nil) userInfo:userInfo] raise];
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
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 _NSJSONSerializationClass = NSClassFromString(@"NSJSONSerialization");
|
||||
SEL _NSJSONSerializationSelector = NSSelectorFromString(@"JSONObjectWithData:options:error:");
|
||||
|
||||
|
||||
#ifdef _AFNETWORKING_PREFER_NSJSONSERIALIZATION_
|
||||
if (_NSJSONSerializationClass && [_NSJSONSerializationClass respondsToSelector:_NSJSONSerializationSelector]) {
|
||||
goto _af_nsjson_decode;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_JSONKitSelector && [data respondsToSelector:_JSONKitSelector]) {
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[data methodSignatureForSelector:_JSONKitSelector]];
|
||||
invocation.target = data;
|
||||
invocation.selector = _JSONKitSelector;
|
||||
|
||||
NSUInteger parseOptionFlags = 0;
|
||||
[invocation setArgument:&parseOptionFlags atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
[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;
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&JSON];
|
||||
} else if (_YAJLSelector && [data respondsToSelector:_YAJLSelector]) {
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[data methodSignatureForSelector:_YAJLSelector]];
|
||||
invocation.target = data;
|
||||
invocation.selector = _YAJLSelector;
|
||||
|
||||
NSUInteger yajlParserOptions = 0;
|
||||
[invocation setArgument:&yajlParserOptions atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
[invocation setArgument:error atIndex:3];
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&JSON];
|
||||
} else if (_NSJSONSerializationClass && [_NSJSONSerializationClass respondsToSelector:_NSJSONSerializationSelector]) {
|
||||
#ifdef _AFNETWORKING_PREFER_NSJSONSERIALIZATION_
|
||||
_af_nsjson_decode:
|
||||
#endif
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[_NSJSONSerializationClass methodSignatureForSelector:_NSJSONSerializationSelector]];
|
||||
invocation.target = _NSJSONSerializationClass;
|
||||
invocation.selector = _NSJSONSerializationSelector;
|
||||
|
||||
[invocation setArgument:&data atIndex:2]; // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
|
||||
NSUInteger readOptions = 0;
|
||||
[invocation setArgument:&readOptions atIndex:3];
|
||||
[invocation setArgument:error atIndex:4];
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:&JSON];
|
||||
} else {
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:NSLocalizedString(@"Please either target a platform that supports NSJSONSerialization or add one of the following libraries to your project: JSONKit, SBJSON, or YAJL", nil) forKey:NSLocalizedRecoverySuggestionErrorKey];
|
||||
[[NSException exceptionWithName:NSInternalInconsistencyException reason:NSLocalizedString(@"No JSON parsing functionality available", nil) userInfo:userInfo] raise];
|
||||
}
|
||||
|
||||
return JSON;
|
||||
}
|
||||
|
|
@ -35,7 +35,6 @@
|
|||
#import "AFHTTPClient.h"
|
||||
|
||||
#import "AFImageRequestOperation.h"
|
||||
#import "AFImagecache.h"
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
#import "AFNetworkActivityIndicatorManager.h"
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ static dispatch_queue_t property_list_request_operation_processing_queue() {
|
|||
}
|
||||
|
||||
- (id)responsePropertyList {
|
||||
if (!_responsePropertyList && [self isFinished]) {
|
||||
if (!_responsePropertyList && [self.responseData length] > 0 && [self isFinished]) {
|
||||
NSPropertyListFormat format;
|
||||
NSError *error = nil;
|
||||
self.responsePropertyList = [NSPropertyListSerialization propertyListWithData:self.responseData options:self.propertyListReadOptions format:&format error:&error];
|
||||
|
|
|
|||
|
|
@ -75,6 +75,10 @@ extern NSString * const AFNetworkingOperationDidFinishNotification;
|
|||
*/
|
||||
@interface AFURLConnectionOperation : NSOperation {
|
||||
@private
|
||||
unsigned short _state;
|
||||
BOOL _cancelled;
|
||||
NSRecursiveLock *_lock;
|
||||
|
||||
NSSet *_runLoopModes;
|
||||
|
||||
NSURLConnection *_connection;
|
||||
|
|
|
|||
|
|
@ -22,14 +22,18 @@
|
|||
|
||||
#import "AFURLConnectionOperation.h"
|
||||
|
||||
static NSUInteger const kAFHTTPMinimumInitialDataCapacity = 1024;
|
||||
static NSUInteger const kAFHTTPMaximumInitialDataCapacity = 1024 * 1024 * 8;
|
||||
|
||||
typedef enum {
|
||||
AFHTTPOperationReadyState = 1,
|
||||
AFHTTPOperationExecutingState = 2,
|
||||
AFHTTPOperationFinishedState = 3,
|
||||
} AFOperationState;
|
||||
} _AFOperationState;
|
||||
|
||||
typedef unsigned short AFOperationState;
|
||||
|
||||
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";
|
||||
|
||||
|
|
@ -52,9 +56,34 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
}
|
||||
}
|
||||
|
||||
static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperationState toState, BOOL isCancelled) {
|
||||
switch (fromState) {
|
||||
case AFHTTPOperationReadyState:
|
||||
switch (toState) {
|
||||
case AFHTTPOperationExecutingState:
|
||||
return YES;
|
||||
case AFHTTPOperationFinishedState:
|
||||
return isCancelled;
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
case AFHTTPOperationExecutingState:
|
||||
switch (toState) {
|
||||
case AFHTTPOperationFinishedState:
|
||||
return YES;
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
case AFHTTPOperationFinishedState:
|
||||
return NO;
|
||||
default:
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
@interface AFURLConnectionOperation ()
|
||||
@property (readwrite, nonatomic, assign) AFOperationState state;
|
||||
@property (readwrite, nonatomic, assign, getter = isCancelled) BOOL cancelled;
|
||||
@property (readwrite, nonatomic, retain) NSRecursiveLock *lock;
|
||||
@property (readwrite, nonatomic, assign) NSURLConnection *connection;
|
||||
@property (readwrite, nonatomic, retain) NSURLRequest *request;
|
||||
@property (readwrite, nonatomic, retain) NSURLResponse *response;
|
||||
|
|
@ -67,14 +96,12 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
@property (readwrite, nonatomic, copy) AFURLConnectionOperationProgressBlock downloadProgress;
|
||||
@property (readwrite, nonatomic, copy) AFURLConnectionOperationAuthenticationChallengeBlock authenticationBlock;
|
||||
|
||||
- (BOOL)shouldTransitionToState:(AFOperationState)state;
|
||||
- (void)operationDidStart;
|
||||
- (void)finish;
|
||||
@end
|
||||
|
||||
@implementation AFURLConnectionOperation
|
||||
@synthesize state = _state;
|
||||
@synthesize cancelled = _cancelled;
|
||||
@synthesize connection = _connection;
|
||||
@synthesize runLoopModes = _runLoopModes;
|
||||
@synthesize request = _request;
|
||||
|
|
@ -89,12 +116,22 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
@synthesize uploadProgress = _uploadProgress;
|
||||
@synthesize downloadProgress = _downloadProgress;
|
||||
@synthesize authenticationBlock = _authenticationBlock;
|
||||
@synthesize lock = _lock;
|
||||
|
||||
+ (void)networkRequestThreadEntryPoint:(id)__unused object {
|
||||
do {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSAutoreleasePool *exceptionPool = [[NSAutoreleasePool alloc] init];
|
||||
NSException *caughtException = nil;
|
||||
@try {
|
||||
NSAutoreleasePool *runLoopPool = [[NSAutoreleasePool alloc] init];
|
||||
[[NSRunLoop currentRunLoop] run];
|
||||
[pool drain];
|
||||
[runLoopPool drain];
|
||||
}
|
||||
@catch(NSException *e) { caughtException = e; }
|
||||
if(caughtException) {
|
||||
NSLog(NSLocalizedString(@"Unhandled exception on %@ networking thread: %@, userInfo: %@", nil), NSStringFromClass([self class]), caughtException, [caughtException userInfo]);
|
||||
}
|
||||
[exceptionPool drain];
|
||||
} while (YES);
|
||||
}
|
||||
|
||||
|
|
@ -116,6 +153,9 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
return nil;
|
||||
}
|
||||
|
||||
self.lock = [[[NSRecursiveLock alloc] init] autorelease];
|
||||
self.lock.name = kAFNetworkingLockName;
|
||||
|
||||
self.runLoopModes = [NSSet setWithObject:NSRunLoopCommonModes];
|
||||
|
||||
self.request = urlRequest;
|
||||
|
|
@ -126,6 +166,8 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_lock release];
|
||||
|
||||
[_runLoopModes release];
|
||||
|
||||
[_request release];
|
||||
|
|
@ -135,7 +177,12 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
[_responseData release];
|
||||
[_responseString release];
|
||||
[_dataAccumulator release];
|
||||
[_outputStream release]; _outputStream = nil;
|
||||
|
||||
if (_outputStream) {
|
||||
[_outputStream close];
|
||||
[_outputStream release];
|
||||
_outputStream = nil;
|
||||
}
|
||||
|
||||
[_uploadProgress release];
|
||||
[_downloadProgress release];
|
||||
|
|
@ -144,7 +191,12 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, state: %@, cancelled: %@ request: %@, response: %@>", NSStringFromClass([self class]), self, AFKeyPathFromOperationState(self.state), ([self isCancelled] ? @"YES" : @"NO"), self.request, self.response];
|
||||
}
|
||||
|
||||
- (void)setCompletionBlock:(void (^)(void))block {
|
||||
[self.lock lock];
|
||||
if (!block) {
|
||||
[super setCompletionBlock:nil];
|
||||
} else {
|
||||
|
|
@ -154,6 +206,7 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
[_blockSelf setCompletionBlock:nil];
|
||||
}];
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (NSInputStream *)inputStream {
|
||||
|
|
@ -179,10 +232,8 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
}
|
||||
|
||||
- (void)setState:(AFOperationState)state {
|
||||
if (![self shouldTransitionToState:state]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self.lock lock];
|
||||
if (AFStateTransitionIsValid(self.state, state, [self isCancelled])) {
|
||||
NSString *oldStateKey = AFKeyPathFromOperationState(self.state);
|
||||
NSString *newStateKey = AFKeyPathFromOperationState(state);
|
||||
|
||||
|
|
@ -203,41 +254,11 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)shouldTransitionToState:(AFOperationState)state {
|
||||
switch (self.state) {
|
||||
case AFHTTPOperationReadyState:
|
||||
switch (state) {
|
||||
case AFHTTPOperationExecutingState:
|
||||
return YES;
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
case AFHTTPOperationExecutingState:
|
||||
switch (state) {
|
||||
case AFHTTPOperationFinishedState:
|
||||
return YES;
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
case AFHTTPOperationFinishedState:
|
||||
return NO;
|
||||
default:
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setCancelled:(BOOL)cancelled {
|
||||
[self willChangeValueForKey:@"isCancelled"];
|
||||
_cancelled = cancelled;
|
||||
[self didChangeValueForKey:@"isCancelled"];
|
||||
|
||||
if ([self isCancelled]) {
|
||||
self.state = AFHTTPOperationFinishedState;
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (NSString *)responseString {
|
||||
[self.lock lock];
|
||||
if (!_responseString && self.response && self.responseData) {
|
||||
NSStringEncoding textEncoding = NSUTF8StringEncoding;
|
||||
if (self.response.textEncodingName) {
|
||||
|
|
@ -246,6 +267,7 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
|
||||
self.responseString = [[[NSString alloc] initWithData:self.responseData encoding:textEncoding] autorelease];
|
||||
}
|
||||
[self.lock unlock];
|
||||
|
||||
return _responseString;
|
||||
}
|
||||
|
|
@ -264,26 +286,29 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
return self.state == AFHTTPOperationFinishedState;
|
||||
}
|
||||
|
||||
- (BOOL)isCancelled {
|
||||
return _cancelled;
|
||||
}
|
||||
|
||||
- (BOOL)isConcurrent {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)start {
|
||||
if (![self isReady]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self.lock lock];
|
||||
if ([self isReady]) {
|
||||
self.state = AFHTTPOperationExecutingState;
|
||||
|
||||
[self performSelector:@selector(operationDidStart) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:YES modes:[self.runLoopModes allObjects]];
|
||||
[self performSelector:@selector(operationDidStart) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (void)operationDidStart {
|
||||
[self.lock lock];
|
||||
if ([self isCancelled]) {
|
||||
[self finish];
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
self.connection = [[[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO] autorelease];
|
||||
|
||||
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
|
||||
|
|
@ -294,21 +319,30 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) {
|
|||
|
||||
[self.connection start];
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (void)finish {
|
||||
self.state = AFHTTPOperationFinishedState;
|
||||
}
|
||||
|
||||
- (void)cancel {
|
||||
if ([self isFinished]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self.lock lock];
|
||||
if (![self isFinished] && ![self isCancelled]) {
|
||||
[super cancel];
|
||||
|
||||
self.cancelled = YES;
|
||||
|
||||
[self willChangeValueForKey:@"isCancelled"];
|
||||
_cancelled = YES;
|
||||
if (self.connection) {
|
||||
[self.connection cancel];
|
||||
|
||||
// We must send this delegate protcol message ourselves since the above [self.connection cancel] causes the connection to never send another message to its delegate.
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[self.request URL] forKey:NSURLErrorFailingURLErrorKey];
|
||||
[self performSelector:@selector(connection:didFailWithError:) withObject:self.connection withObject:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:userInfo]];
|
||||
}
|
||||
[self didChangeValueForKey:@"isCancelled"];
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
#pragma mark - NSURLConnectionDelegate
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ static dispatch_queue_t xml_request_operation_processing_queue() {
|
|||
}
|
||||
|
||||
- (NSXMLParser *)responseXMLParser {
|
||||
if (!_responseXMLParser && [self isFinished]) {
|
||||
if (!_responseXMLParser && [self.responseData length] > 0 && [self isFinished]) {
|
||||
self.responseXMLParser = [[[NSXMLParser alloc] initWithData:self.responseData] autorelease];
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +148,7 @@ static dispatch_queue_t xml_request_operation_processing_queue() {
|
|||
|
||||
#if __MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
- (NSXMLDocument *)responseXMLDocument {
|
||||
if (!_responseXMLDocument && [self isFinished]) {
|
||||
if (!_responseXMLDocument && [self.responseData length] > 0 && [self isFinished]) {
|
||||
NSError *error = nil;
|
||||
self.responseXMLDocument = [[[NSXMLDocument alloc] initWithData:self.responseData options:0 error:&error] autorelease];
|
||||
self.error = error;
|
||||
|
|
|
|||
|
|
@ -24,10 +24,20 @@
|
|||
#import <objc/runtime.h>
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
|
||||
#import "UIImageView+AFNetworking.h"
|
||||
|
||||
#import "AFImageCache.h"
|
||||
@interface AFImageCache : NSCache
|
||||
@property (nonatomic, assign) CGFloat imageScale;
|
||||
|
||||
- (UIImage *)cachedImageForURL:(NSURL *)url
|
||||
cacheName:(NSString *)cacheName;
|
||||
|
||||
- (void)cacheImageData:(NSData *)imageData
|
||||
forURL:(NSURL *)url
|
||||
cacheName:(NSString *)cacheName;
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
static char kAFImageRequestOperationObjectKey;
|
||||
|
||||
|
|
@ -52,14 +62,24 @@ static char kAFImageRequestOperationObjectKey;
|
|||
}
|
||||
|
||||
+ (NSOperationQueue *)af_sharedImageRequestOperationQueue {
|
||||
static NSOperationQueue *_imageRequestOperationQueue = nil;
|
||||
static NSOperationQueue *_af_imageRequestOperationQueue = nil;
|
||||
|
||||
if (!_imageRequestOperationQueue) {
|
||||
_imageRequestOperationQueue = [[NSOperationQueue alloc] init];
|
||||
[_imageRequestOperationQueue setMaxConcurrentOperationCount:8];
|
||||
if (!_af_imageRequestOperationQueue) {
|
||||
_af_imageRequestOperationQueue = [[NSOperationQueue alloc] init];
|
||||
[_af_imageRequestOperationQueue setMaxConcurrentOperationCount:8];
|
||||
}
|
||||
|
||||
return _imageRequestOperationQueue;
|
||||
return _af_imageRequestOperationQueue;
|
||||
}
|
||||
|
||||
+ (AFImageCache *)af_sharedImageCache {
|
||||
static AFImageCache *_af_imageCache = nil;
|
||||
static dispatch_once_t oncePredicate;
|
||||
dispatch_once(&oncePredicate, ^{
|
||||
_af_imageCache = [[AFImageCache alloc] init];
|
||||
});
|
||||
|
||||
return _af_imageCache;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
|
@ -89,7 +109,7 @@ static char kAFImageRequestOperationObjectKey;
|
|||
[self cancelImageRequestOperation];
|
||||
}
|
||||
|
||||
UIImage *cachedImage = [[AFImageCache sharedImageCache] cachedImageForURL:[urlRequest URL] cacheName:nil];
|
||||
UIImage *cachedImage = [[[self class] af_sharedImageCache] cachedImageForURL:[urlRequest URL] cacheName:nil];
|
||||
if (cachedImage) {
|
||||
self.image = cachedImage;
|
||||
self.af_imageRequestOperation = nil;
|
||||
|
|
@ -104,15 +124,13 @@ static char kAFImageRequestOperationObjectKey;
|
|||
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
|
||||
if ([[urlRequest URL] isEqual:[[self.af_imageRequestOperation request] URL]]) {
|
||||
self.image = responseObject;
|
||||
} else {
|
||||
self.image = placeholderImage;
|
||||
}
|
||||
|
||||
if (success) {
|
||||
success(operation.request, operation.response, responseObject);
|
||||
}
|
||||
|
||||
[[AFImageCache sharedImageCache] cacheImageData:operation.responseData forURL:[urlRequest URL] cacheName:nil];
|
||||
[[[self class] af_sharedImageCache] cacheImageData:operation.responseData forURL:[urlRequest URL] cacheName:nil];
|
||||
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
|
||||
if (failure) {
|
||||
failure(operation.request, operation.response, error);
|
||||
|
|
@ -131,4 +149,43 @@ static char kAFImageRequestOperationObjectKey;
|
|||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
static inline NSString * AFImageCacheKeyFromURLAndCacheName(NSURL *url, NSString *cacheName) {
|
||||
return [[url absoluteString] stringByAppendingFormat:@"#%@", cacheName];
|
||||
}
|
||||
|
||||
@implementation AFImageCache
|
||||
@synthesize imageScale = _imageScale;
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.imageScale = [[UIScreen mainScreen] scale];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (UIImage *)cachedImageForURL:(NSURL *)url
|
||||
cacheName:(NSString *)cacheName
|
||||
{
|
||||
UIImage *image = [UIImage imageWithData:[self objectForKey:AFImageCacheKeyFromURLAndCacheName(url, cacheName)]];
|
||||
if (image) {
|
||||
return [UIImage imageWithCGImage:[image CGImage] scale:self.imageScale orientation:image.imageOrientation];
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
- (void)cacheImageData:(NSData *)imageData
|
||||
forURL:(NSURL *)url
|
||||
cacheName:(NSString *)cacheName
|
||||
{
|
||||
[self setObject:[NSPurgeableData dataWithData:imageData] forKey:AFImageCacheKeyFromURLAndCacheName(url, cacheName)];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
|
|
|||
57
CHANGES
Normal file
57
CHANGES
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
= 0.9.0 / 2012-01-23
|
||||
|
||||
* Add thread-safe behavior to `AFURLConnectionOperation` (Mattt Thompson)
|
||||
|
||||
* Add batching of operations for `AFHTTPClient` (Mattt Thompson)
|
||||
|
||||
* Add authentication challenge callback block to override default implementation of `connection:didReceiveAuthenticationChallenge:` in `AFURLConnectionOperation` (Mattt Thompson)
|
||||
|
||||
* Add `_AFNETWORKING_PREFER_NSJSONSERIALIZATION_`, which, when defined, short-circuits the standard preference ordering used in `AFJSONEncode` and `AFJSONDecode` to use `NSJSONSerialization` when available, falling back on third-party-libraries. (Mattt Thompson, Shane Vitarana)
|
||||
|
||||
* Add custom `description` for `AFURLConnectionOperation` and `AFHTTPClient` (Mattt Thompson)
|
||||
|
||||
* Add `text/javascript` to default acceptable content types for `AFJSONRequestOperation` (Jake Boxer)
|
||||
|
||||
* Add `imageScale` property to change resolution of images constructed from cached data (Štěpán Petrů)
|
||||
|
||||
* Add note about third party JSON libraries in README (David Keegan)
|
||||
|
||||
* `AFQueryStringFromParametersWithEncoding` formats `NSArray` values in the form `key[]=value1&key[]=value2` instead of `key=(value1,value2)` (Dan Thorpe)
|
||||
|
||||
* `AFImageRequestOperation -responseImage` on OS X uses `NSBitmapImageRep` to determine the correct pixel dimensions of the image (David Keegan)
|
||||
|
||||
* `AFURLConnectionOperation` `connection` has memory management policy `assign` to avoid retain cycles caused by `NSURLConnection` retaining its delegate (Mattt Thompson)
|
||||
|
||||
* `AFURLConnectionOperation` calls super implementation for `-isReady`, following the guidelines for `NSOperation` subclasses (Mattt Thompson)
|
||||
|
||||
* `UIImageView -setImageWithURL:` and related methods call success callback after setting image (Cameron Boehmer)
|
||||
|
||||
* Cancel request if an authentication challenge has no suitable credentials in `AFURLConnectionOperation -connection:didReceiveAuthenticationChallenge:` (Jorge Bernal)
|
||||
|
||||
* Remove exception from `multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:` raised when certain HTTP methods are used. (Mattt Thompson)
|
||||
|
||||
* Remove `AFImageCache` from public API, moving it into private implementation of `UIImageView+AFNetworking` (Mattt Thompson)
|
||||
|
||||
* Mac example application makes better use of AppKit technologies and conventions (Mattt Thompson)
|
||||
|
||||
* Fix issue with multipart form boundaries in `AFHTTPClient -multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:` (Ray Morgan, Mattt Thompson, Sam Soffes)
|
||||
|
||||
* Fix "File Upload with Progress Callback" code snippet in README (Larry Legend)
|
||||
|
||||
* Fix to SBJSON invocations in `AFJSONEncode` and `AFJSONDecode` (Matthias Tretter, James Frye)
|
||||
|
||||
* Fix documentation for `AFHTTPClient requestWithMethod:path:parameters:` (Michael Parker)
|
||||
|
||||
* Fix `Content-Disposition` headers used for multipart form construction (Michael Parker)
|
||||
|
||||
* Add network reachability status change callback property to `AFHTTPClient`. (Mattt Thompson, Kevin Harwood)
|
||||
|
||||
* Fix exception handling in `AFJSONEncode` and `AFJSONDecode` (David Keegan)
|
||||
|
||||
* Fix `NSData` initialization with string in `AFBase64EncodedStringFromString` (Adam Ernst, Mattt Thompson)
|
||||
|
||||
* Fix error check in `appendPartWithFileURL:name:error:` (Warren Moore, Baldoph, Mattt Thompson)
|
||||
|
||||
* Fix compiler warnings for certain configurations (Charlie Williams)
|
||||
|
||||
* Fix bug caused by passing zero-length `responseData` to response object initializers (Mattt Thompson, Serge Paquet)
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
F8689A9C14CC9F780087F357 /* AFJSONUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = F8689A9B14CC9F780087F357 /* AFJSONUtilities.m */; };
|
||||
F87A159F1444926300318955 /* AFURLConnectionOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F87A159E1444926300318955 /* AFURLConnectionOperation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
||||
F87A15A21444926A00318955 /* AFXMLRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F87A15A11444926900318955 /* AFXMLRequestOperation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
||||
F87A15A51444927300318955 /* AFPropertyListRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F87A15A41444927300318955 /* AFPropertyListRequestOperation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
||||
|
|
@ -17,7 +18,6 @@
|
|||
F87A15DD1444A86600318955 /* placeholder-stamp.png in Resources */ = {isa = PBXBuildFile; fileRef = F87A15DB1444A86600318955 /* placeholder-stamp.png */; };
|
||||
F897DE78142CFEDC000DDD35 /* AFHTTPClient.m in Sources */ = {isa = PBXBuildFile; fileRef = F897DE6A142CFEDC000DDD35 /* AFHTTPClient.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
||||
F897DE79142CFEDC000DDD35 /* AFHTTPRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F897DE6C142CFEDC000DDD35 /* AFHTTPRequestOperation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
||||
F897DE7A142CFEDC000DDD35 /* AFImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = F897DE6E142CFEDC000DDD35 /* AFImageCache.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
||||
F897DE7B142CFEDC000DDD35 /* AFImageRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F897DE70142CFEDC000DDD35 /* AFImageRequestOperation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
||||
F897DE7C142CFEDC000DDD35 /* AFJSONRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F897DE72142CFEDC000DDD35 /* AFJSONRequestOperation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
||||
F8A27AC7142CFE1300F5E0D6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F8A27AB2142CFE1300F5E0D6 /* AppDelegate.m */; };
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
/* Begin PBXFileReference section */
|
||||
F8323C901455B4FE00190CCB /* AFJSONUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFJSONUtilities.h; sourceTree = "<group>"; };
|
||||
F8689A9B14CC9F780087F357 /* AFJSONUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFJSONUtilities.m; sourceTree = "<group>"; };
|
||||
F87A159D1444926300318955 /* AFURLConnectionOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLConnectionOperation.h; sourceTree = "<group>"; };
|
||||
F87A159E1444926300318955 /* AFURLConnectionOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLConnectionOperation.m; sourceTree = "<group>"; };
|
||||
F87A15A01444926900318955 /* AFXMLRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFXMLRequestOperation.h; sourceTree = "<group>"; };
|
||||
|
|
@ -48,8 +49,6 @@
|
|||
F897DE6A142CFEDC000DDD35 /* AFHTTPClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPClient.m; sourceTree = "<group>"; };
|
||||
F897DE6B142CFEDC000DDD35 /* AFHTTPRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPRequestOperation.h; sourceTree = "<group>"; };
|
||||
F897DE6C142CFEDC000DDD35 /* AFHTTPRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPRequestOperation.m; sourceTree = "<group>"; };
|
||||
F897DE6D142CFEDC000DDD35 /* AFImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFImageCache.h; sourceTree = "<group>"; };
|
||||
F897DE6E142CFEDC000DDD35 /* AFImageCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFImageCache.m; sourceTree = "<group>"; };
|
||||
F897DE6F142CFEDC000DDD35 /* AFImageRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFImageRequestOperation.h; sourceTree = "<group>"; };
|
||||
F897DE70142CFEDC000DDD35 /* AFImageRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFImageRequestOperation.m; sourceTree = "<group>"; };
|
||||
F897DE71142CFEDC000DDD35 /* AFJSONRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFJSONRequestOperation.h; sourceTree = "<group>"; };
|
||||
|
|
@ -139,9 +138,8 @@
|
|||
F897DE6A142CFEDC000DDD35 /* AFHTTPClient.m */,
|
||||
F897DE6F142CFEDC000DDD35 /* AFImageRequestOperation.h */,
|
||||
F897DE70142CFEDC000DDD35 /* AFImageRequestOperation.m */,
|
||||
F897DE6D142CFEDC000DDD35 /* AFImageCache.h */,
|
||||
F897DE6E142CFEDC000DDD35 /* AFImageCache.m */,
|
||||
F8323C901455B4FE00190CCB /* AFJSONUtilities.h */,
|
||||
F8689A9B14CC9F780087F357 /* AFJSONUtilities.m */,
|
||||
);
|
||||
name = AFNetworking;
|
||||
path = ../../AFNetworking;
|
||||
|
|
@ -288,7 +286,6 @@
|
|||
F8A27ACB142CFE1300F5E0D6 /* JSONKit.m in Sources */,
|
||||
F897DE78142CFEDC000DDD35 /* AFHTTPClient.m in Sources */,
|
||||
F897DE79142CFEDC000DDD35 /* AFHTTPRequestOperation.m in Sources */,
|
||||
F897DE7A142CFEDC000DDD35 /* AFImageCache.m in Sources */,
|
||||
F897DE7B142CFEDC000DDD35 /* AFImageRequestOperation.m in Sources */,
|
||||
F897DE7C142CFEDC000DDD35 /* AFJSONRequestOperation.m in Sources */,
|
||||
F87A159F1444926300318955 /* AFURLConnectionOperation.m in Sources */,
|
||||
|
|
@ -297,6 +294,7 @@
|
|||
F87A15CD1444A30800318955 /* AFGowallaAPIClient.m in Sources */,
|
||||
F87A15CE1444A30800318955 /* NearbySpotsController.m in Sources */,
|
||||
F87A15CF1444A30800318955 /* Spot.m in Sources */,
|
||||
F8689A9C14CC9F780087F357 /* AFJSONUtilities.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@
|
|||
<object class="NSWindowTemplate" id="972006081">
|
||||
<int key="NSWindowStyleMask">15</int>
|
||||
<int key="NSWindowBacking">2</int>
|
||||
<string key="NSWindowRect">{{50, 538}, {375, 500}}</string>
|
||||
<string key="NSWindowRect">{{60, 295}, {375, 500}}</string>
|
||||
<int key="NSWTFlags">1954021376</int>
|
||||
<string key="NSWindowTitle">AFNetworking Mac Example</string>
|
||||
<string key="NSWindowClass">NSWindow</string>
|
||||
|
|
@ -439,7 +439,6 @@
|
|||
<string key="NSFrame">{{1, 526}, {374, 15}}</string>
|
||||
<reference key="NSSuperview" ref="905625827"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:1216</string>
|
||||
<int key="NSsFlags">1</int>
|
||||
<reference key="NSTarget" ref="905625827"/>
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
F8689A9914CC9F5E0087F357 /* AFJSONUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = F8689A9814CC9F5E0087F357 /* AFJSONUtilities.m */; };
|
||||
F86E5529143A28F3002B438C /* AFURLConnectionOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F86E5528143A28F3002B438C /* AFURLConnectionOperation.m */; };
|
||||
F874B5D913E0AA6500B28E3E /* AFHTTPRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F874B5C913E0AA6500B28E3E /* AFHTTPRequestOperation.m */; };
|
||||
F874B5DA13E0AA6500B28E3E /* AFImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = F874B5CA13E0AA6500B28E3E /* AFImageCache.m */; };
|
||||
F874B5DB13E0AA6500B28E3E /* AFImageRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F874B5CB13E0AA6500B28E3E /* AFImageRequestOperation.m */; };
|
||||
F874B5DC13E0AA6500B28E3E /* AFJSONRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F874B5CC13E0AA6500B28E3E /* AFJSONRequestOperation.m */; };
|
||||
F874B5DD13E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F874B5CD13E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.m */; };
|
||||
|
|
@ -41,16 +41,15 @@
|
|||
|
||||
/* Begin PBXFileReference section */
|
||||
F8323C941455C03400190CCB /* AFJSONUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFJSONUtilities.h; path = ../AFNetworking/AFJSONUtilities.h; sourceTree = "<group>"; };
|
||||
F8689A9814CC9F5E0087F357 /* AFJSONUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFJSONUtilities.m; path = ../AFNetworking/AFJSONUtilities.m; sourceTree = "<group>"; };
|
||||
F86E5527143A28F3002B438C /* AFURLConnectionOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFURLConnectionOperation.h; path = ../AFNetworking/AFURLConnectionOperation.h; sourceTree = "<group>"; };
|
||||
F86E5528143A28F3002B438C /* AFURLConnectionOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFURLConnectionOperation.m; path = ../AFNetworking/AFURLConnectionOperation.m; sourceTree = "<group>"; };
|
||||
F874B5C913E0AA6500B28E3E /* AFHTTPRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFHTTPRequestOperation.m; path = ../AFNetworking/AFHTTPRequestOperation.m; sourceTree = "<group>"; };
|
||||
F874B5CA13E0AA6500B28E3E /* AFImageCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFImageCache.m; path = ../AFNetworking/AFImageCache.m; sourceTree = "<group>"; };
|
||||
F874B5CB13E0AA6500B28E3E /* AFImageRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFImageRequestOperation.m; path = ../AFNetworking/AFImageRequestOperation.m; sourceTree = "<group>"; };
|
||||
F874B5CC13E0AA6500B28E3E /* AFJSONRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFJSONRequestOperation.m; path = ../AFNetworking/AFJSONRequestOperation.m; sourceTree = "<group>"; };
|
||||
F874B5CD13E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFNetworkActivityIndicatorManager.m; path = ../AFNetworking/AFNetworkActivityIndicatorManager.m; sourceTree = "<group>"; };
|
||||
F874B5D013E0AA6500B28E3E /* UIImageView+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImageView+AFNetworking.m"; path = "../AFNetworking/UIImageView+AFNetworking.m"; sourceTree = "<group>"; };
|
||||
F874B5D113E0AA6500B28E3E /* AFHTTPRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFHTTPRequestOperation.h; path = ../AFNetworking/AFHTTPRequestOperation.h; sourceTree = "<group>"; };
|
||||
F874B5D213E0AA6500B28E3E /* AFImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFImageCache.h; path = ../AFNetworking/AFImageCache.h; sourceTree = "<group>"; };
|
||||
F874B5D313E0AA6500B28E3E /* AFImageRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFImageRequestOperation.h; path = ../AFNetworking/AFImageRequestOperation.h; sourceTree = "<group>"; };
|
||||
F874B5D413E0AA6500B28E3E /* AFJSONRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFJSONRequestOperation.h; path = ../AFNetworking/AFJSONRequestOperation.h; sourceTree = "<group>"; };
|
||||
F874B5D513E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFNetworkActivityIndicatorManager.h; path = ../AFNetworking/AFNetworkActivityIndicatorManager.h; sourceTree = "<group>"; };
|
||||
|
|
@ -246,13 +245,12 @@
|
|||
F8FBFA97142AA238001409DB /* AFHTTPClient.m */,
|
||||
F874B5D313E0AA6500B28E3E /* AFImageRequestOperation.h */,
|
||||
F874B5CB13E0AA6500B28E3E /* AFImageRequestOperation.m */,
|
||||
F874B5D213E0AA6500B28E3E /* AFImageCache.h */,
|
||||
F874B5CA13E0AA6500B28E3E /* AFImageCache.m */,
|
||||
F874B5D813E0AA6500B28E3E /* UIImageView+AFNetworking.h */,
|
||||
F874B5D013E0AA6500B28E3E /* UIImageView+AFNetworking.m */,
|
||||
F874B5D513E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.h */,
|
||||
F874B5CD13E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.m */,
|
||||
F8323C941455C03400190CCB /* AFJSONUtilities.h */,
|
||||
F8689A9814CC9F5E0087F357 /* AFJSONUtilities.m */,
|
||||
);
|
||||
name = AFNetworking;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -356,7 +354,6 @@
|
|||
F8DA09E41396AC040057D0CC /* main.m in Sources */,
|
||||
F8DA09E81396AC220057D0CC /* AppDelegate.m in Sources */,
|
||||
F874B5D913E0AA6500B28E3E /* AFHTTPRequestOperation.m in Sources */,
|
||||
F874B5DA13E0AA6500B28E3E /* AFImageCache.m in Sources */,
|
||||
F874B5DB13E0AA6500B28E3E /* AFImageRequestOperation.m in Sources */,
|
||||
F874B5DC13E0AA6500B28E3E /* AFJSONRequestOperation.m in Sources */,
|
||||
F874B5DD13E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.m in Sources */,
|
||||
|
|
@ -365,6 +362,7 @@
|
|||
F86E5529143A28F3002B438C /* AFURLConnectionOperation.m in Sources */,
|
||||
F8F4B16E143CD1420064C9E6 /* AFPropertyListRequestOperation.m in Sources */,
|
||||
F8F4B17F143E07030064C9E6 /* AFXMLRequestOperation.m in Sources */,
|
||||
F8689A9914CC9F5E0087F357 /* AFJSONUtilities.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#import "SpotTableViewCell.h"
|
||||
|
||||
#import "TTTLocationFormatter.h"
|
||||
#import "AFImageCache.h"
|
||||
#import "UIImageView+AFNetworking.h"
|
||||
|
||||
@interface NearbySpotsViewController ()
|
||||
|
|
@ -123,7 +122,6 @@
|
|||
self.nearbySpots = [NSArray array];
|
||||
[self.tableView reloadData];
|
||||
[[NSURLCache sharedURLCache] removeAllCachedResponses];
|
||||
[[AFImageCache sharedImageCache] removeAllObjects];
|
||||
|
||||
if (self.locationManager.location) {
|
||||
[self loadSpotsForLocation:self.locationManager.location];
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@
|
|||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue