Merge branch 'master' into experimental-mac

Conflicts:
	AFNetworking/AFNetworkActivityIndicatorManager.m
	iOS Example/AFNetworking iOS Example.xcodeproj/project.pbxproj
This commit is contained in:
Mattt Thompson 2011-10-11 09:58:00 -05:00
commit 80a0c65608
16 changed files with 304 additions and 227 deletions

View file

@ -1,11 +1,11 @@
Pod::Spec.new do
name 'AFNetworking'
version '0.6.0'
version '0.6.1'
summary 'A delightful iOS networking library with NSOperations and block-based callbacks'
homepage 'https://github.com/gowalla/AFNetworking'
authors 'Mattt Thompson' => 'm@mattt.me', 'Scott Raymond' => 'sco@gowalla.com'
source :git => 'https://github.com/gowalla/AFNetworking.git',
:tag => '0.6.0'
:tag => '0.6.1'
platforms 'iOS'
sdk '>= 4.0'

View file

@ -23,10 +23,27 @@
#import <Foundation/Foundation.h>
#import "AFHTTPRequestOperation.h"
@protocol AFMultipartFormDataProxy;
@protocol AFMultipartFormData;
/**
`AFHTTPClient` objects encapsulates the common patterns of communicating with an application, webservice, or API. It encapsulates persistent information, like base URL, authorization credentials, and HTTP headers, and uses them to construct and manage the execution of HTTP request operations.
In its default implementation, `AFHTTPClient` sets the following HTTP headers:
- `Accept: application/json`
- `Accept-Encoding: gzip`
- `Accept-Language: #{[NSLocale preferredLanguages]}, en-us;q=0.8`
- `User-Agent: #{generated user agent}`
You can override these HTTP headers or define new ones using `setDefaultHeader:value:`.
# Subclassing Notes
It is strongly recommended that you create an `AFHTTPClient` subclass for each website or web application that your application communicates with, and in each subclass, defining a method that returns a singleton object that acts as single a shared HTTP client that holds authentication credentials and other configuration for the entire application.
## Methods to Override
If an `AFHTTPClient` wishes to change the way request parameters are encoded, then the base implementation of `requestWithMethod:path:parameters: should be overridden. Otherwise, it should be sufficient to take the `super` implementation, and configure the resulting `NSMutableURLRequest` object accordingly.
*/
@interface AFHTTPClient : NSObject {
@private
@ -36,6 +53,10 @@
NSOperationQueue *_operationQueue;
}
///---------------------------------------
/// @name Accessing HTTP Client Properties
///---------------------------------------
/**
The url used as the base for paths specified in methods such as `getPath:parameteres:success:failure`
*/
@ -49,7 +70,7 @@
/**
The operation queue which manages operations enqueued by the HTTP client.
*/
@property (readonly, nonatomic, retain) NSOperationQueue *operationQueue;;
@property (readonly, nonatomic, retain) NSOperationQueue *operationQueue;
///---------------------------------------------
/// @name Creating and Initializing HTTP Clients
@ -80,7 +101,7 @@
///----------------------------------
/**
Returns the value for the HTTP headers set in request objects created by the HTTP client
Returns the value for the HTTP headers set in request objects created by the HTTP client.
@param header The HTTP header to return the default value for
@ -130,24 +151,25 @@
@return An `NSMutableURLRequest` object
*/
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
path:(NSString *)path parameters:(NSDictionary *)parameters;
path:(NSString *)path
parameters:(NSDictionary *)parameters;
/**
Creates an `NSMutableURLRequest` object with the specified HTTP method and path, and constructs a `multipart/form-data` HTTP body, using the specified parameters and multipart form data block.
Creates an `NSMutableURLRequest` object with the specified HTTP method and path, and constructs a `multipart/form-data` HTTP body, using the specified parameters and multipart form data block. See http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2
@param method The HTTP method for the request. Must be either `POST`, `PUT`, or `DELETE`.
@param path The path to be appended to the HTTP client's base URL and used as the request URL.
@param parameters The parameters to be encoded and set in the request HTTP body.
@param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormDataProxy` protocol. This can be used to upload files, encode HTTP body as JSON or XML, or specify multiple values for the same parameter, as one might for array values.
@param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. This can be used to upload files, encode HTTP body as JSON or XML, or specify multiple values for the same parameter, as one might for array values.
@see AFMultipartFormDataProxy
@see AFMultipartFormData
@return An `NSMutableURLRequest` object
*/
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
path:(NSString *)path
parameters:(NSDictionary *)parameters
constructingBodyWithBlock:(void (^)(id <AFMultipartFormDataProxy>formData))block;
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block;
///--------------------------------
@ -158,12 +180,12 @@
Creates and enqueues an `AFHTTPRequestOperation` to the HTTP client's operation queue.
@param request The request object to be loaded asynchronously during execution of the operation.
@param success A block object to be executed when the request operation finishes successfully, with a status code in the 2xx range, and with an acceptable content type (e.g. `application/json`). This block has no return value and takes a single argument, which is the response object created from the response data of request.
@param success A block object to be executed when the request operation finishes successfully, with a status code in the 2xx range, and with an acceptable content type (e.g. `application/json`). This block has no return value and takes a single argument, which is an object created from the response data of request.
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the resonse data as JSON. This block has no return value and takes a single argument, which is the `NSError` object describing the network or parsing error that occurred.
*/
- (void)enqueueHTTPOperationWithRequest:(NSURLRequest *)request
success:(void (^)(id response))success
failure:(void (^)(NSError *error))failure;
success:(void (^)(id object))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure;
///---------------------------------
/// @name Cancelling HTTP Operations
@ -188,11 +210,13 @@
@param parameters The parameters to be encoded and appended as the query string for the request URL.
@param success A block object to be executed when the request operation finishes successfully, with a status code in the 2xx range, and with an acceptable content type (e.g. `application/json`). This block has no return value and takes a single argument, which is the response object created from the response data of request.
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the resonse data as JSON. This block has no return value and takes a single argument, which is the `NSError` object describing the network or parsing error that occurred.
@see enqueueHTTPOperationWithRequest:success:failure
*/
- (void)getPath:(NSString *)path
parameters:(NSDictionary *)parameters
success:(void (^)(id response))success
failure:(void (^)(NSError *error))failure;
success:(void (^)(id object))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure;
/**
Creates an `AFHTTPRequestOperation` with a `POST` request, and enqueues it to the HTTP client's operation queue.
@ -201,11 +225,13 @@
@param parameters The parameters to be encoded and set in the request HTTP body.
@param success A block object to be executed when the request operation finishes successfully, with a status code in the 2xx range, and with an acceptable content type (e.g. `application/json`). This block has no return value and takes a single argument, which is the response object created from the response data of request.
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the resonse data as JSON. This block has no return value and takes a single argument, which is the `NSError` object describing the network or parsing error that occurred.
@see enqueueHTTPOperationWithRequest:success:failure
*/
- (void)postPath:(NSString *)path
parameters:(NSDictionary *)parameters
success:(void (^)(id response))success
failure:(void (^)(NSError *error))failure;
success:(void (^)(id object))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure;
/**
Creates an `AFHTTPRequestOperation` with a `PUT` request, and enqueues it to the HTTP client's operation queue.
@ -214,11 +240,13 @@
@param parameters The parameters to be encoded and set in the request HTTP body.
@param success A block object to be executed when the request operation finishes successfully, with a status code in the 2xx range, and with an acceptable content type (e.g. `application/json`). This block has no return value and takes a single argument, which is the response object created from the response data of request.
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the resonse data as JSON. This block has no return value and takes a single argument, which is the `NSError` object describing the network or parsing error that occurred.
@see enqueueHTTPOperationWithRequest:success:failure
*/
- (void)putPath:(NSString *)path
parameters:(NSDictionary *)parameters
success:(void (^)(id response))success
failure:(void (^)(NSError *error))failure;
success:(void (^)(id object))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure;
/**
Creates an `AFHTTPRequestOperation` with a `DELETE` request, and enqueues it to the HTTP client's operation queue.
@ -227,19 +255,21 @@
@param parameters The parameters to be encoded and set in the request HTTP body.
@param success A block object to be executed when the request operation finishes successfully, with a status code in the 2xx range, and with an acceptable content type (e.g. `application/json`). This block has no return value and takes a single argument, which is the response object created from the response data of request.
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the resonse data as JSON. This block has no return value and takes a single argument, which is the `NSError` object describing the network or parsing error that occurred.
@see enqueueHTTPOperationWithRequest:success:failure
*/
- (void)deletePath:(NSString *)path
parameters:(NSDictionary *)parameters
success:(void (^)(id response))success
failure:(void (^)(NSError *error))failure;
success:(void (^)(id object))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure;
@end
#pragma mark -
/**
The `AFMultipartFormDataProxy` protocol defines the methods supported by the parameter in the block argument of `multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:`.
The `AFMultipartFormData` protocol defines the methods supported by the parameter in the block argument of `multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:`.
*/
@protocol AFMultipartFormDataProxy <NSObject>
@protocol AFMultipartFormData
/**
Appends HTTP headers, followed by the encoded data and the multipart form boundary.
@ -250,13 +280,23 @@
- (void)appendPartWithHeaders:(NSDictionary *)headers body:(NSData *)body;
/**
Appends the HTTP headers `Content-Disposition: form-data; name=#{name}"` and, if mimeType is specified, `Content-Type: #{mimeType}`, followed by the encoded data and the multipart form boundary.
Appends the HTTP headers `Content-Disposition: form-data; name=#{name}"`, followed by the encoded data and the multipart form boundary.
@param data The data to be encoded and appended to the form data.
@param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. If `nil`, the `Content-Type` header will be omitted.
@param name The name to be associated with the specified data. This parameter must not be `nil`.
*/
- (void)appendPartWithFormData:(NSData *)data mimeType:(NSString *)mimeType name:(NSString *)name;
- (void)appendPartWithFormData:(NSData *)data name:(NSString *)name;
/**
Appends the HTTP header `Content-Disposition: file; filename=#{generated filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary.
@param data The data to be encoded and appended to the form data.
@param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`.
@param name The name to be associated with the specified data. This parameter must not be `nil`.
@discussion The filename associated with this data in the form will be automatically generated using the parameter name specified and a unique timestamp-based hash.
*/
- (void)appendPartWithFileData:(NSData *)data mimeType:(NSString *)mimeType name:(NSString *)name;
/**
Appends the HTTP header `Content-Disposition: file; filename=#{filename}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary.
@ -264,8 +304,9 @@
@param fileURL The URL for the local file to have its contents appended to the form data. This parameter must not be `nil`.
@param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`.
@param fileName The filename to be associated with the file contents. This parameter must not be `nil`.
@param error If an error occurs, upon return contains an `NSError` object that describes the problem.
*/
- (void)appendPartWithFile:(NSURL *)fileURL mimeType:(NSString *)mimeType fileName:(NSString *)fileName;
- (void)appendPartWithFile:(NSURL *)fileURL mimeType:(NSString *)mimeType fileName:(NSString *)fileName error:(NSError **)error;
/**
Appends encoded data to the form data.

View file

@ -26,20 +26,14 @@
static NSString * const kAFMultipartFormLineDelimiter = @"\r\n"; // CRLF
static NSString * const kAFMultipartFormBoundary = @"Boundary+0xAbCdEfGbOuNdArY";
static NSString * AFMultipartFormEncapsulationBoundary() {
return [NSString stringWithFormat:@"--%@", kAFMultipartFormBoundary];
}
static NSString * AFMultipartFormFinalBoundary() {
return [NSString stringWithFormat:@"--%@--", kAFMultipartFormBoundary];
}
@interface AFMutableMultipartFormData : NSMutableData <AFMultipartFormDataProxy> {
@interface AFMultipartFormData : NSObject <AFMultipartFormData> {
@private
NSStringEncoding _stringEncoding;
NSRange _finalBoundaryRange;
NSMutableData *_mutableData;
}
@property (readonly) NSData *data;
- (id)initWithStringEncoding:(NSStringEncoding)encoding;
@end
@ -63,9 +57,9 @@ static NSString * AFBase64EncodedStringFromString(NSString *string) {
}
}
static char const kAFBase64EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static uint8_t const kAFBase64EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
NSInteger idx = (i / 3) * 4;
NSUInteger idx = (i / 3) * 4;
output[idx + 0] = kAFBase64EncodingTable[(value >> 18) & 0x3F];
output[idx + 1] = kAFBase64EncodingTable[(value >> 12) & 0x3F];
output[idx + 2] = (i + 1) < length ? kAFBase64EncodingTable[(value >> 6) & 0x3F] : '=';
@ -140,7 +134,7 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
}
- (void)setDefaultHeader:(NSString *)header value:(NSString *)value {
[self.defaultHeaders setObject:value forKey:header];
[self.defaultHeaders setValue:value forKey:header];
}
- (void)setAuthorizationHeaderWithUsername:(NSString *)username password:(NSString *)password {
@ -158,7 +152,10 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
#pragma mark -
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method path:(NSString *)path parameters:(NSDictionary *)parameters {
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
path:(NSString *)path
parameters:(NSDictionary *)parameters
{
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
NSMutableDictionary *headers = [NSMutableDictionary dictionaryWithDictionary:self.defaultHeaders];
NSURL *url = [NSURL URLWithString:path relativeToURL:self.baseURL];
@ -175,14 +172,13 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
url = [NSURL URLWithString:[[url absoluteString] stringByAppendingFormat:[path rangeOfString:@"?"].location == NSNotFound ? @"?%@" : @"&%@", queryString]];
} else {
NSString *charset = (NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(self.stringEncoding));
[headers setObject:[NSString stringWithFormat:@"application/x-www-form-urlencoded; charset=%@", charset] forKey:@"Content-Type"];
[headers setValue:[NSString stringWithFormat:@"application/x-www-form-urlencoded; charset=%@", charset] forKey:@"Content-Type"];
[request setHTTPBody:[queryString dataUsingEncoding:self.stringEncoding]];
}
}
[request setURL:url];
[request setHTTPMethod:method];
[request setHTTPShouldHandleCookies:NO];
[request setAllHTTPHeaderFields:headers];
return request;
@ -191,7 +187,7 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
path:(NSString *)path
parameters:(NSDictionary *)parameters
constructingBodyWithBlock:(void (^)(id <AFMultipartFormDataProxy>formData))block
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData>formData))block
{
if (!([method isEqualToString:@"POST"] || [method isEqualToString:@"PUT"] || [method isEqualToString:@"DELETE"])) {
[NSException raise:@"Invalid HTTP Method" format:@"%@ is not supported for multipart form requests; must be either POST, PUT, or DELETE", method];
@ -199,7 +195,7 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
}
NSMutableURLRequest *request = [self requestWithMethod:method path:path parameters:nil];
__block AFMutableMultipartFormData *formData = [[AFMutableMultipartFormData alloc] initWithStringEncoding:self.stringEncoding];
__block AFMultipartFormData *formData = [[AFMultipartFormData alloc] initWithStringEncoding:self.stringEncoding];
id key = nil;
NSEnumerator *enumerator = [parameters keyEnumerator];
@ -213,7 +209,7 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
data = [[value description] dataUsingEncoding:self.stringEncoding];
}
[formData appendPartWithHeaders:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"form-data; name=\"%@\"", [key description]] forKey:@"Content-Disposition"] body:value];
[formData appendPartWithFormData:data name:[key description]];
}
if (block) {
@ -221,19 +217,27 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
}
[request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", kAFMultipartFormBoundary] forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:formData];
[request setHTTPBody:[formData data]];
[formData autorelease];
return request;
}
- (void)enqueueHTTPOperationWithRequest:(NSURLRequest *)request success:(void (^)(id response))success failure:(void (^)(NSError *error))failure {
if ([request URL] == nil || [[request URL] isEqual:[NSNull null]]) {
return;
- (void)enqueueHTTPOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(id object))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
{
AFJSONRequestOperation *operation = [AFJSONRequestOperation operationWithRequest:urlRequest success:^(id JSON) {
if (success) {
success(JSON);
}
} failure:^(NSHTTPURLResponse *response, NSError *error) {
if (failure) {
failure(response, error);
}
}];
AFHTTPRequestOperation *operation = [AFJSONRequestOperation operationWithRequest:request success:success failure:failure];
[self.operationQueue addOperation:operation];
}
@ -247,22 +251,38 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
#pragma mark -
- (void)getPath:(NSString *)path parameters:(NSDictionary *)parameters success:(void (^)(id response))success failure:(void (^)(NSError *error))failure {
- (void)getPath:(NSString *)path
parameters:(NSDictionary *)parameters
success:(void (^)(id object))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
{
NSURLRequest *request = [self requestWithMethod:@"GET" path:path parameters:parameters];
[self enqueueHTTPOperationWithRequest:request success:success failure:failure];
}
- (void)postPath:(NSString *)path parameters:(NSDictionary *)parameters success:(void (^)(id response))success failure:(void (^)(NSError *error))failure {
- (void)postPath:(NSString *)path
parameters:(NSDictionary *)parameters
success:(void (^)(id object))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
{
NSURLRequest *request = [self requestWithMethod:@"POST" path:path parameters:parameters];
[self enqueueHTTPOperationWithRequest:request success:success failure:failure];
}
- (void)putPath:(NSString *)path parameters:(NSDictionary *)parameters success:(void (^)(id response))success failure:(void (^)(NSError *error))failure {
- (void)putPath:(NSString *)path
parameters:(NSDictionary *)parameters
success:(void (^)(id object))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
{
NSURLRequest *request = [self requestWithMethod:@"PUT" path:path parameters:parameters];
[self enqueueHTTPOperationWithRequest:request success:success failure:failure];
}
- (void)deletePath:(NSString *)path parameters:(NSDictionary *)parameters success:(void (^)(id response))success failure:(void (^)(NSError *error))failure {
- (void)deletePath:(NSString *)path
parameters:(NSDictionary *)parameters
success:(void (^)(id object))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
{
NSURLRequest *request = [self requestWithMethod:@"DELETE" path:path parameters:parameters];
[self enqueueHTTPOperationWithRequest:request success:success failure:failure];
}
@ -271,17 +291,22 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
#pragma mark -
// multipart/form-data; see http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2
@interface AFMutableMultipartFormData ()
@property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding;
@property (readwrite, nonatomic, assign) NSRange finalBoundaryRange;
static inline NSString * AFMultipartFormEncapsulationBoundary() {
return [NSString stringWithFormat:@"%@--%@%@", kAFMultipartFormLineDelimiter, kAFMultipartFormBoundary, kAFMultipartFormLineDelimiter];
}
- (void)appendBlankLine;
static inline NSString * AFMultipartFormFinalBoundary() {
return [NSString stringWithFormat:@"%@--%@--", kAFMultipartFormLineDelimiter, kAFMultipartFormBoundary];
}
@interface AFMultipartFormData ()
@property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding;
@property (readwrite, nonatomic, retain) NSMutableData *mutableData;
@end
@implementation AFMutableMultipartFormData
@implementation AFMultipartFormData
@synthesize stringEncoding = _stringEncoding;
@synthesize finalBoundaryRange = _finalBoundaryRange;
@synthesize mutableData = _mutableData;
- (id)initWithStringEncoding:(NSStringEncoding)encoding {
self = [super init];
@ -290,66 +315,69 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
}
self.stringEncoding = encoding;
self.finalBoundaryRange = NSMakeRange(0, 0);
self.mutableData = [NSMutableData dataWithLength:0];
return self;
}
#pragma mark - AFMultipartFormDataProxy
- (void)dealloc {
[_mutableData release];
[super dealloc];
}
- (NSData *)data {
NSMutableData *finalizedData = [NSMutableData dataWithData:self.mutableData];
[finalizedData appendData:[AFMultipartFormFinalBoundary() dataUsingEncoding:self.stringEncoding]];
return finalizedData;
}
#pragma mark - AFMultipartFormData
- (void)appendPartWithHeaders:(NSDictionary *)headers body:(NSData *)body {
if ([self length] > 0) {
[self appendString:AFMultipartFormEncapsulationBoundary()];
}
for (NSString *field in [headers allKeys]) {
[self appendString:[NSString stringWithFormat:@"%@: %@", field, [headers valueForKey:field]]];
[self appendString:[NSString stringWithFormat:@"%@: %@%@", field, [headers valueForKey:field], kAFMultipartFormLineDelimiter]];
}
[self appendBlankLine];
[self appendString:kAFMultipartFormLineDelimiter];
[self appendData:body];
}
- (void)appendPartWithFormData:(NSData *)data mimeType:(NSString *)mimeType name:(NSString *)name {
- (void)appendPartWithFormData:(NSData *)data name:(NSString *)name {
NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary];
[mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"", name] forKey:@"Content-Disposition"];
if (mimeType) {
[mutableHeaders setValue:mimeType forKey:@"Content-Type"];
}
[self appendPartWithHeaders:mutableHeaders body:data];
}
- (void)appendPartWithFile:(NSURL *)fileURL mimeType:(NSString *)mimeType fileName:(NSString *)fileName {
if (![fileURL isFileURL]) {
[NSException raise:@"Invalid fileURL value" format:@"%@ must be a valid file URL", fileURL];
return;
}
- (void)appendPartWithFileData:(NSData *)data mimeType:(NSString *)mimeType name:(NSString *)name {
NSString *fileName = [[NSString stringWithFormat:@"%@-%d", name, [[NSDate date] hash]] stringByAppendingPathExtension:[mimeType lastPathComponent]];
NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary];
[mutableHeaders setValue:[NSString stringWithFormat:@"file; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"];
[mutableHeaders setValue:mimeType forKey:@"Content-Type"];
[self appendPartWithHeaders:mutableHeaders body:data];
}
- (void)appendPartWithFile:(NSURL *)fileURL mimeType:(NSString *)mimeType fileName:(NSString *)fileName error:(NSError **)error {
NSData *data = [NSData dataWithContentsOfFile:[fileURL absoluteString] options:0 error:error];
if (data) {
NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary];
[mutableHeaders setValue:[NSString stringWithFormat:@"file; filename=\"%@\"", fileName] forKey:@"Content-Disposition"];
[mutableHeaders setValue:mimeType forKey:@"Content-Type"];
NSData *data = [NSData dataWithContentsOfFile:[fileURL absoluteString]];
[self appendPartWithHeaders:mutableHeaders body:data];
}
}
- (void)appendData:(NSData *)data {
NSMutableData *mutableData = [NSMutableData dataWithData:data];
[self replaceBytesInRange:self.finalBoundaryRange withBytes:[mutableData bytes]];
NSData *finalBoundary = [AFMultipartFormFinalBoundary() dataUsingEncoding:self.stringEncoding];
self.finalBoundaryRange = NSMakeRange([self length], [finalBoundary length]);
[super appendData:finalBoundary];
[self.mutableData appendData:data];
}
- (void)appendString:(NSString *)string {
[self appendData:[string dataUsingEncoding:self.stringEncoding]];
}
- (void)appendBlankLine {
[self appendString:@""];
}
@end

View file

@ -48,10 +48,25 @@ extern NSString * const AFHTTPOperationDidFinishNotification;
For instance, `AFJSONRequestOperation` makes a distinction between successful and unsuccessful requests by validating the HTTP status code and content type of the response, and provides separate callbacks for both the succeeding and failing cases. As another example, `AFImageRequestOperation` offers a pared-down callback, with a single block argument that is an image object that was created from the response data.
## Methods to subclass
## Methods to Subclass
Unless you need to override specific `NSURLConnection` delegate methods, you shouldn't need to subclass any methods. Instead, you should provide alternative constructor class methods, that are essentially wrappers around the callback from `AFHTTPRequestOperation`.
### `NSURLConnection` Delegate Methods
Notably, `AFHTTPRequestOperation` does not implement any of the authentication challenge-related `NSURLConnection` delegate methods.
`AFHTTPRequestOperation` does implement the following `NSURLConnection` delegate methods:
- `connection:didReceiveResponse:`
- `connection:didReceiveData:`
- `connectionDidFinishLoading:`
- `connection:didFailWithError:`
- `connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:`
- `connection:willCacheResponse:`
If you overwrite any of the above methods, be sure to make the call to `super` first, or else it may cause unexpected results.
@see NSOperation
@see NSURLConnection
*/
@ -65,7 +80,7 @@ extern NSString * const AFHTTPOperationDidFinishNotification;
NSError *_error;
NSData *_responseBody;
NSUInteger _totalBytesRead;
NSInteger _totalBytesRead;
NSMutableData *_dataAccumulator;
NSOutputStream *_outputStream;
}
@ -89,26 +104,24 @@ extern NSString * const AFHTTPOperationDidFinishNotification;
@param urlRequest The request object to be loaded asynchronously during execution of the operation.
@param completion A block object to be executed when the HTTP request operation is finished. This block has no return value and takes four arguments: the request sent from the client, the response received from the server, the HTTP body received by the server during the execution of the request, and an error, which will have been set if an error occured while loading the request.
@see operationWithRequest:inputStream:outputStream:completion
@return A new HTTP request operation
*/
+ (AFHTTPRequestOperation *)operationWithRequest:(NSURLRequest *)urlRequest
completion:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSData *data, NSError *error))completion;
/**
Creates and returns a streaming `AFHTTPRequestOperation` object and sets the specified input and output streams, and completion callback.
Creates and returns a streaming `AFHTTPRequestOperation` object and sets the specified input stream, output stream, and completion callback.
@param urlRequest The request object to be loaded asynchronously during execution of the operation.
@param inputStream The input stream object for reading data to be sent during the request. If set, the input stream is set as the HTTPBodyStream on the NSMutableURLRequest, and the request method is changed to `POST`. This argument may be `nil`.
@param inputStream The input stream object for reading data to be sent during the request. If set, the input stream is set as the `HTTPBodyStream` on the `NSMutableURLRequest`. If the request method is `GET`, it is changed to `POST`. This argument may be `nil`.
@param outputStream The output stream object for writing data received during the request. If set, data accumulated in `NSURLConnectionDelegate` methods will be sent to the output stream, and the NSData parameter in the completion block will be `nil`. This argument may be `nil`.
@param completion A block object to be executed when the HTTP request operation is finished. This block has no return value and takes four arguments: the request sent from the client, the response received from the server, the NSData received by the server during the execution of the request, and an error, which will have been set if an error occured while loading the request. This argument may be `nil`.
@param completion A block object to be executed when the HTTP request operation is finished. This block has no return value and takes four arguments: the request sent from the client, the response received from the server, the data received by the server during the execution of the request, and an error, which will have been set if an error occured while loading the request. This argument may be `nil`.
@see operationWithRequest:completion
@return A new HTTP request operation
@return A new streaming HTTP request operation
*/
+ (AFHTTPRequestOperation *)operationWithRequest:(NSURLRequest *)urlRequest
+ (AFHTTPRequestOperation *)streamingOperationWithRequest:(NSURLRequest *)urlRequest
inputStream:(NSInputStream *)inputStream
outputStream:(NSOutputStream *)outputStream
completion:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))completion;
@ -120,19 +133,19 @@ extern NSString * const AFHTTPOperationDidFinishNotification;
/**
Sets a callback to be called when an undetermined number of bytes have been downloaded from the server.
@param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes two arguments: the total bytes written, and the total bytes expected to be written during the request, as initially determined by the length of the HTTP body. This block may be called multiple times.
@param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the number of bytes written since the last time the upload progress block was called, the total bytes written, and the total bytes expected to be written during the request, as initially determined by the length of the HTTP body. This block may be called multiple times.
@see setDownloadProgressBlock
*/
- (void)setUploadProgressBlock:(void (^)(NSUInteger totalBytesWritten, NSUInteger totalBytesExpectedToWrite))block;
- (void)setUploadProgressBlock:(void (^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))block;
/**
Sets a callback to be called when an undetermined number of bytes have been uploaded to the server.
@param block A block object to be called when an undetermined number of bytes have been uploaded to the server. This block has no return value and takes two arguments: the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times.
@param block A block object to be called when an undetermined number of bytes have been uploaded to the server. This block has no return value and takes three arguments: the number of bytes read since the last time the upload progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times.
@see setUploadProgressBlock
*/
- (void)setDownloadProgressBlock:(void (^)(NSUInteger totalBytesRead, NSUInteger totalBytesExpectedToRead))block;
- (void)setDownloadProgressBlock:(void (^)(NSInteger bytesRead, NSInteger totalBytesRead, NSInteger totalBytesExpectedToRead))block;
@end

View file

@ -21,7 +21,6 @@
// THE SOFTWARE.
#import "AFHTTPRequestOperation.h"
#import "AFNetworkActivityIndicatorManager.h"
static NSUInteger const kAFHTTPMinimumInitialDataCapacity = 1024;
static NSUInteger const kAFHTTPMaximumInitialDataCapacity = 1024 * 1024 * 8;
@ -38,7 +37,7 @@ NSString * const AFNetworkingErrorDomain = @"com.alamofire.networking.error";
NSString * const AFHTTPOperationDidStartNotification = @"com.alamofire.networking.http-operation.start";
NSString * const AFHTTPOperationDidFinishNotification = @"com.alamofire.networking.http-operation.finish";
typedef void (^AFHTTPRequestOperationProgressBlock)(NSUInteger totalBytes, NSUInteger totalBytesExpected);
typedef void (^AFHTTPRequestOperationProgressBlock)(NSInteger bytes, NSInteger totalBytes, NSInteger totalBytesExpected);
typedef void (^AFHTTPRequestOperationCompletionBlock)(NSURLRequest *request, NSHTTPURLResponse *response, NSData *data, NSError *error);
static inline NSString * AFKeyPathFromOperationState(AFHTTPOperationState state) {
@ -85,14 +84,13 @@ static inline BOOL AFHTTPOperationStateTransitionIsValid(AFHTTPOperationState fr
@property (readwrite, nonatomic, retain) NSHTTPURLResponse *response;
@property (readwrite, nonatomic, retain) NSError *error;
@property (readwrite, nonatomic, retain) NSData *responseBody;
@property (readwrite, nonatomic, assign) NSUInteger totalBytesRead;
@property (readwrite, nonatomic, assign) NSInteger totalBytesRead;
@property (readwrite, nonatomic, retain) NSMutableData *dataAccumulator;
@property (readwrite, nonatomic, retain) NSOutputStream *outputStream;
@property (readwrite, nonatomic, copy) AFHTTPRequestOperationProgressBlock uploadProgress;
@property (readwrite, nonatomic, copy) AFHTTPRequestOperationProgressBlock downloadProgress;
@property (readwrite, nonatomic, copy) AFHTTPRequestOperationCompletionBlock completion;
- (id)initWithRequest:(NSURLRequest *)urlRequest;
- (void)operationDidStart;
- (void)finish;
@end
@ -115,7 +113,7 @@ static inline BOOL AFHTTPOperationStateTransitionIsValid(AFHTTPOperationState fr
static NSThread *_networkRequestThread = nil;
+ (void)networkRequestThreadEntryPoint:(id)object {
+ (void)networkRequestThreadEntryPoint:(id)__unused object {
do {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[[NSRunLoop currentRunLoop] run];
@ -137,13 +135,14 @@ static NSThread *_networkRequestThread = nil;
+ (AFHTTPRequestOperation *)operationWithRequest:(NSURLRequest *)urlRequest
completion:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSData *data, NSError *error))completion
{
AFHTTPRequestOperation *operation = [[[self alloc] initWithRequest:urlRequest] autorelease];
AFHTTPRequestOperation *operation = [[[self alloc] init] autorelease];
operation.request = urlRequest;
operation.completion = completion;
return operation;
}
+ (AFHTTPRequestOperation *)operationWithRequest:(NSURLRequest *)urlRequest
+ (AFHTTPRequestOperation *)streamingOperationWithRequest:(NSURLRequest *)urlRequest
inputStream:(NSInputStream *)inputStream
outputStream:(NSOutputStream *)outputStream
completion:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))completion
@ -156,7 +155,7 @@ static NSThread *_networkRequestThread = nil;
}
}
AFHTTPRequestOperation *operation = [self operationWithRequest:mutableURLRequest completion:^(NSURLRequest *request, NSHTTPURLResponse *response, NSData *data, NSError *error) {
AFHTTPRequestOperation *operation = [self operationWithRequest:mutableURLRequest completion:^(NSURLRequest *request, NSHTTPURLResponse *response, __unused NSData *data, NSError *error) {
if (completion) {
completion(request, response, error);
}
@ -167,14 +166,12 @@ static NSThread *_networkRequestThread = nil;
return operation;
}
- (id)initWithRequest:(NSURLRequest *)urlRequest {
- (id)init {
self = [super init];
if (!self) {
return nil;
}
self.request = urlRequest;
self.runLoopModes = [NSSet setWithObject:NSRunLoopCommonModes];
self.state = AFHTTPOperationReadyState;
@ -199,11 +196,11 @@ static NSThread *_networkRequestThread = nil;
[super dealloc];
}
- (void)setUploadProgressBlock:(void (^)(NSUInteger totalBytesWritten, NSUInteger totalBytesExpectedToWrite))block {
- (void)setUploadProgressBlock:(void (^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))block {
self.uploadProgress = block;
}
- (void)setDownloadProgressBlock:(void (^)(NSUInteger totalBytesRead, NSUInteger totalBytesExpectedToRead))block {
- (void)setDownloadProgressBlock:(void (^)(NSInteger bytesRead, NSInteger totalBytesRead, NSInteger totalBytesExpectedToRead))block {
self.downloadProgress = block;
}
@ -228,11 +225,9 @@ static NSThread *_networkRequestThread = nil;
#if __IPHONE_OS_VERSION_MIN_REQUIRED
switch (state) {
case AFHTTPOperationExecutingState:
[[AFNetworkActivityIndicatorManager sharedManager] incrementActivityCount];
[[NSNotificationCenter defaultCenter] postNotificationName:AFHTTPOperationDidStartNotification object:self];
break;
case AFHTTPOperationFinishedState:
[[AFNetworkActivityIndicatorManager sharedManager] decrementActivityCount];
[[NSNotificationCenter defaultCenter] postNotificationName:AFHTTPOperationDidFinishNotification object:self];
break;
default:
@ -327,7 +322,7 @@ static NSThread *_networkRequestThread = nil;
#pragma mark - NSURLConnection
- (void)connection:(NSURLConnection *)connection
- (void)connection:(NSURLConnection *)__unused connection
didReceiveResponse:(NSURLResponse *)response
{
self.response = (NSHTTPURLResponse *)response;
@ -335,12 +330,14 @@ didReceiveResponse:(NSURLResponse *)response
if (self.outputStream) {
[self.outputStream open];
} else {
NSUInteger capacity = MIN(MAX(abs(response.expectedContentLength), kAFHTTPMinimumInitialDataCapacity), kAFHTTPMaximumInitialDataCapacity);
NSUInteger maxCapacity = MAX((NSUInteger)llabs(response.expectedContentLength), kAFHTTPMinimumInitialDataCapacity);
NSUInteger capacity = MIN(maxCapacity, kAFHTTPMaximumInitialDataCapacity);
self.dataAccumulator = [NSMutableData dataWithCapacity:capacity];
}
}
- (void)connection:(NSURLConnection *)connection
- (void)connection:(NSURLConnection *)__unused connection
didReceiveData:(NSData *)data
{
self.totalBytesRead += [data length];
@ -355,11 +352,11 @@ didReceiveResponse:(NSURLResponse *)response
}
if (self.downloadProgress) {
self.downloadProgress(self.totalBytesRead, self.response.expectedContentLength);
self.downloadProgress([data length], self.totalBytesRead, (NSInteger)self.response.expectedContentLength);
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
- (void)connectionDidFinishLoading:(NSURLConnection *)__unused connection {
if (self.outputStream) {
[self.outputStream close];
} else {
@ -370,7 +367,7 @@ didReceiveResponse:(NSURLResponse *)response
[self finish];
}
- (void)connection:(NSURLConnection *)connection
- (void)connection:(NSURLConnection *)__unused connection
didFailWithError:(NSError *)error
{
self.error = error;
@ -384,17 +381,17 @@ didReceiveResponse:(NSURLResponse *)response
[self finish];
}
- (void)connection:(NSURLConnection *)connection
- (void)connection:(NSURLConnection *)__unused connection
didSendBodyData:(NSInteger)bytesWritten
totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
if (self.uploadProgress) {
self.uploadProgress(totalBytesWritten, totalBytesExpectedToWrite);
self.uploadProgress(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
}
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
- (NSCachedURLResponse *)connection:(NSURLConnection *)__unused connection
willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
if ([self isCancelled]) {

View file

@ -55,7 +55,7 @@
@param urlRequest The request object to be loaded asynchronously during execution of the operation
@param success A block object to be executed when the JSON request operation finishes successfully, with a status code in the 2xx range, and with an acceptable content type (e.g. `application/json`). This block has no return value and takes a single argument, which is the JSON object created from the response data of request.
@param failure A block object to be executed when the JSON request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the resonse data as JSON. This block has no return value and takes a single argument, which is the error describing the network or parsing error that occurred.
@param failure A block object to be executed when the JSON request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the resonse data as JSON. This block has no return value and takes a two arguments: the response from the server, and the error describing the network or parsing error that occurred.
@see defaultAcceptableStatusCodes
@see defaultAcceptableContentTypes
@ -65,7 +65,7 @@
*/
+ (AFJSONRequestOperation *)operationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(id JSON))success
failure:(void (^)(NSError *error))failure;
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure;
/**
Creates and returns an `AFJSONRequestOperation` object and sets the specified success and failure callbacks, as well as the status codes and content types that are acceptable for a successful request.

View file

@ -44,15 +44,15 @@ static dispatch_queue_t json_request_operation_processing_queue() {
+ (AFJSONRequestOperation *)operationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(id JSON))success
failure:(void (^)(NSError *error))failure
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure
{
return [self operationWithRequest:urlRequest acceptableStatusCodes:[self defaultAcceptableStatusCodes] acceptableContentTypes:[self defaultAcceptableContentTypes] success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
return [self operationWithRequest:urlRequest acceptableStatusCodes:[self defaultAcceptableStatusCodes] acceptableContentTypes:[self defaultAcceptableContentTypes] success:^(NSURLRequest __unused *request, NSHTTPURLResponse __unused *response, id JSON) {
if (success) {
success(JSON);
}
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
} failure:^(NSURLRequest __unused *request, NSHTTPURLResponse *response, NSError *error) {
if (failure) {
failure(error);
failure(response, error);
}
}];
}

View file

@ -23,15 +23,23 @@
#import <Foundation/Foundation.h>
/**
`AFNetworkActivityIndicatorManager` manages the state of the network activity indicator in the status bar. When network operations start, they can call `-incrementActivityCount`, and once they're finished, call `-decrementActivityCount`. 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.
*/
#if __IPHONE_OS_VERSION_MIN_REQUIRED
@interface AFNetworkActivityIndicatorManager : NSObject {
@private
NSInteger _activityCount;
BOOL _enabled;
}
/**
A Boolean value indicating whether the manager is enabled.
@discussion If YES, the manager will change status bar network activity indicator according to network operation notifications it receives. The default value is NO.
*/
@property (nonatomic, assign, getter = isEnabled) BOOL enabled;
/**
Returns the shared network activity indicator manager object for the system.

View file

@ -22,30 +22,52 @@
#import "AFNetworkActivityIndicatorManager.h"
#if __IPHONE_OS_VERSION_MIN_REQUIRED
#import "AFHTTPRequestOperation.h"
@interface AFNetworkActivityIndicatorManager ()
@property (readwrite, nonatomic, assign) NSInteger activityCount;
@end
@implementation AFNetworkActivityIndicatorManager
@synthesize activityCount = _activityCount;
@synthesize enabled = _enabled;
+ (AFNetworkActivityIndicatorManager *)sharedManager {
static AFNetworkActivityIndicatorManager *_sharedManager = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedManager = [[AFNetworkActivityIndicatorManager alloc] init];
_sharedManager = [[self alloc] init];
});
return _sharedManager;
}
- (id)init {
self = [super init];
if (!self) {
return nil;
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(incrementActivityCount) name:AFHTTPOperationDidStartNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(decrementActivityCount) name:AFHTTPOperationDidFinishNotification object:nil];
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (void)setActivityCount:(NSInteger)activityCount {
[self willChangeValueForKey:@"activityCount"];
_activityCount = MAX(activityCount, 0);
[self didChangeValueForKey:@"activityCount"];
if (self.enabled) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:self.activityCount > 0];
}
}
- (void)incrementActivityCount {
@ -61,4 +83,3 @@
}
@end
#endif

View file

@ -47,9 +47,7 @@
@param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the image view will not change its image until the image request finishes.
@discussion By default, url requests have a cache policy of `NSURLCacheStorageAllowed` and a timeout interval of 30 seconds, and are set to use HTTP pipelining, and not handle cookies. To configure url requests differently, use `setImageWithURLRequest:placeholderImage:success:failure:`
@warning If `placeholderImage` is specified, the remote image will be resized to the dimensions of the placeholder image before being set.
*/
*/
- (void)setImageWithURL:(NSURL *)url
placeholderImage:(UIImage *)placeholderImage;
@ -61,11 +59,8 @@
@param success A block to be executed when the image request operation finishes successfully, with a status code in the 2xx range, and with an acceptable content type (e.g. `image/png`). This block has no return value and takes three arguments, the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the request and response parameters will be `nil`.
@param failure A block object to be executed when the image request operation finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments, the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred.
@discussion By default, url requests have a cache policy of `NSURLCacheStorageAllowed` and a timeout interval of 30 seconds, and are set to use HTTP pipelining, and not handle cookies. To configure url requests differently, use `setImageWithURLRequest:placeholderImage:success:failure:`
@warning If `placeholderImage` is specified, the remote image will be resized to the dimensions of the placeholder image before being set.
*/
*/
- (void)setImageWithURLRequest:(NSURLRequest *)urlRequest
placeholderImage:(UIImage *)placeholderImage
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image))success

View file

@ -29,36 +29,7 @@
#import "AFImageCache.h"
static UIImage * AFImageByScalingAndCroppingImageToSize(UIImage *image, CGSize size) {
if (image == nil) {
return nil;
} else if (CGSizeEqualToSize(image.size, size) || CGSizeEqualToSize(size, CGSizeZero)) {
return image;
}
CGSize scaledSize = size;
CGPoint thumbnailPoint = CGPointZero;
CGFloat widthFactor = size.width / image.size.width;
CGFloat heightFactor = size.height / image.size.height;
CGFloat scaleFactor = (widthFactor > heightFactor) ? widthFactor : heightFactor;
scaledSize.width = image.size.width * scaleFactor;
scaledSize.height = image.size.height * scaleFactor;
if (widthFactor > heightFactor) {
thumbnailPoint.y = (size.height - scaledSize.height) * 0.5;
} else if (widthFactor < heightFactor) {
thumbnailPoint.x = (size.width - scaledSize.width) * 0.5;
}
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
[image drawInRect:CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledSize.width, scaledSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
static NSString * const kUIImageViewImageRequestObjectKey = @"_af_imageRequestOperation";
static NSString * const kAFImageRequestOperationObjectKey = @"_af_imageRequestOperation";
@interface UIImageView (_AFNetworking)
@property (readwrite, nonatomic, retain, setter = af_setImageRequestOperation:) AFImageRequestOperation *af_imageRequestOperation;
@ -73,11 +44,11 @@ static NSString * const kUIImageViewImageRequestObjectKey = @"_af_imageRequestOp
@implementation UIImageView (AFNetworking)
- (AFHTTPRequestOperation *)af_imageRequestOperation {
return (AFHTTPRequestOperation *)objc_getAssociatedObject(self, kUIImageViewImageRequestObjectKey);
return (AFHTTPRequestOperation *)objc_getAssociatedObject(self, kAFImageRequestOperationObjectKey);
}
- (void)af_setImageRequestOperation:(AFImageRequestOperation *)imageRequestOperation {
objc_setAssociatedObject(self, kUIImageViewImageRequestObjectKey, imageRequestOperation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(self, kAFImageRequestOperationObjectKey, imageRequestOperation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (NSOperationQueue *)af_sharedImageRequestOperationQueue {
@ -118,12 +89,7 @@ static NSString * const kUIImageViewImageRequestObjectKey = @"_af_imageRequestOp
[self cancelImageRequestOperation];
}
NSString *cacheName = @"UIImageView";
if (placeholderImage) {
cacheName = [cacheName stringByAppendingFormat:@"(%@)", NSStringFromCGSize(placeholderImage.size)];
}
UIImage *cachedImage = [[AFImageCache sharedImageCache] cachedImageForURL:[urlRequest URL] cacheName:cacheName];
UIImage *cachedImage = [[AFImageCache sharedImageCache] cachedImageForURL:[urlRequest URL] cacheName:nil];
if (cachedImage) {
self.image = cachedImage;
@ -133,13 +99,7 @@ static NSString * const kUIImageViewImageRequestObjectKey = @"_af_imageRequestOp
} else {
self.image = placeholderImage;
self.af_imageRequestOperation = [AFImageRequestOperation operationWithRequest:urlRequest imageProcessingBlock:^UIImage *(UIImage *image) {
if (placeholderImage) {
image = AFImageByScalingAndCroppingImageToSize(image, placeholderImage.size);
}
return image;
} cacheName:cacheName success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
self.af_imageRequestOperation = [AFImageRequestOperation operationWithRequest:urlRequest imageProcessingBlock:nil cacheName:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
if (self.af_imageRequestOperation && ![self.af_imageRequestOperation isCancelled]) {
dispatch_async(dispatch_get_main_queue(), ^{
if (success) {

View file

@ -233,7 +233,7 @@ static inline double CLLocationSpeedToMilesPerHour(CLLocationSpeed speed) {
case TTTWestDirection:
return NSLocalizedString(@"W", @"West Direction Abbreviation");
case TTTNorthwestDirection:
return NSLocalizedString(@"NW", @"Northwest Direction Abbreviation");;
return NSLocalizedString(@"NW", @"Northwest Direction Abbreviation");
}
break;
case TTTBearingNumericStyle:

View file

@ -53,7 +53,7 @@ UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0
``` objective-c
NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:@"avatar.jpg"], 0.5);
NSMutableURLRequest *request = [[AFHTTPClient sharedClient] multipartFormRequestWithMethod:@"POST" path:@"/upload" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormDataProxy>formData) {
NSMutableURLRequest *request = [[AFHTTPClient sharedClient] multipartFormRequestWithMethod:@"POST" path:@"/upload" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
[formData appendPartWithFormData:data name:@"avatar"];
}];
@ -97,7 +97,7 @@ NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:8080/encode"]];
NSInputStream *inputStream = [NSInputStream inputStreamWithFileAtPath:[[NSBundle mainBundle] pathForResource:@"large-image" ofType:@"tiff"]];
NSOutputStream *outputStream = [NSOutputStream outputStreamToMemory];
AFHTTPRequestOperation *operation = [AFHTTPRequestOperation operationWithRequest:request inputStream:inputStream outputStream:outputStream completion:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
AFHTTPRequestOperation *operation = [AFHTTPRequestOperation streamingOperationWithRequest:request inputStream:inputStream outputStream:outputStream completion:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(@"Streaming operation complete");
}];
```
@ -113,7 +113,7 @@ In order to demonstrate the power and flexibility of AFNetworking, we've include
### ARC Support
If you are including AFNetworking in a project with [Automatic Reference Counting (ARC)](http://clang.llvm.org/docs/AutomaticReferenceCounting.html) enabled, you will need to set the `-fno-obj-arc` compiler flag on all of the AFNetworking source files. To do this in Xcode, go to your active target and select the "Build Phases" tab. In the "Compiler Flags" column, set `-fno-obj-arc` for each of the AFNetworking source files.
If you are including AFNetworking in a project with [Automatic Reference Counting (ARC)](http://clang.llvm.org/docs/AutomaticReferenceCounting.html) enabled, you will need to set the `-fno-objc-arc` compiler flag on all of the AFNetworking source files. To do this in Xcode, go to your active target and select the "Build Phases" tab. In the "Compiler Flags" column, set `-fno-objc-arc` for each of the AFNetworking source files.
This is certainly suboptimal, forking the project into an ARC and non-ARC branch would be extremely difficult to maintain. On the bright side, we're very excited about [CocoaPods](https://github.com/alloy/cocoapods), which is a promising solution to this and many other pain points.

View file

@ -13,8 +13,11 @@
F874B5DC13E0AA6500B28E3E /* AFJSONRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F874B5CC13E0AA6500B28E3E /* AFJSONRequestOperation.m */; };
F874B5DD13E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F874B5CD13E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.m */; };
F874B5E013E0AA6500B28E3E /* UIImageView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = F874B5D013E0AA6500B28E3E /* UIImageView+AFNetworking.m */; };
F8D0701B14310F4A00653FD3 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469E213957DF700DB05C8 /* SystemConfiguration.framework */; };
F8D0701C14310F4F00653FD3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469E013957DF100DB05C8 /* Security.framework */; };
F8D25D191396A9D300CF3BD6 /* placeholder-stamp.png in Resources */ = {isa = PBXBuildFile; fileRef = F8D25D171396A9D300CF3BD6 /* placeholder-stamp.png */; };
F8D25D1A1396A9D300CF3BD6 /* placeholder-stamp@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F8D25D181396A9D300CF3BD6 /* placeholder-stamp@2x.png */; };
F8DA09D21396ABED0057D0CC /* AFGowallaAPIClient.m in Sources */ = {isa = PBXBuildFile; fileRef = F8D25D1D1396A9DE00CF3BD6 /* AFGowallaAPIClient.m */; };
F8DA09D41396ABED0057D0CC /* NearbySpotsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F8DA09C81396AB690057D0CC /* NearbySpotsViewController.m */; };
F8DA09D51396ABED0057D0CC /* Spot.m in Sources */ = {isa = PBXBuildFile; fileRef = F8DA09CB1396AB690057D0CC /* Spot.m */; };
F8DA09D61396ABED0057D0CC /* SpotTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F8DA09CE1396AB690057D0CC /* SpotTableViewCell.m */; };
@ -27,7 +30,6 @@
F8E469691395739D00DB05C8 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469681395739D00DB05C8 /* CoreGraphics.framework */; };
F8E469DF13957DD500DB05C8 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469DE13957DD500DB05C8 /* CoreLocation.framework */; };
F8FBFA98142AA239001409DB /* AFHTTPClient.m in Sources */ = {isa = PBXBuildFile; fileRef = F8FBFA97142AA238001409DB /* AFHTTPClient.m */; };
FF2B770D140DAC4E00A8DEC2 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FF2B770C140DAC4E00A8DEC2 /* libz.dylib */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -49,6 +51,8 @@
F8D25D141396A9C400CF3BD6 /* TTTLocationFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTTLocationFormatter.m; sourceTree = "<group>"; };
F8D25D171396A9D300CF3BD6 /* placeholder-stamp.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "placeholder-stamp.png"; path = "Images/placeholder-stamp.png"; sourceTree = SOURCE_ROOT; };
F8D25D181396A9D300CF3BD6 /* placeholder-stamp@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "placeholder-stamp@2x.png"; path = "Images/placeholder-stamp@2x.png"; sourceTree = SOURCE_ROOT; };
F8D25D1B1396A9DE00CF3BD6 /* AFGowallaAPIClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFGowallaAPIClient.h; path = Classes/AFGowallaAPIClient.h; sourceTree = "<group>"; };
F8D25D1D1396A9DE00CF3BD6 /* AFGowallaAPIClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFGowallaAPIClient.m; path = Classes/AFGowallaAPIClient.m; sourceTree = "<group>"; };
F8DA09C71396AB690057D0CC /* NearbySpotsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NearbySpotsViewController.h; sourceTree = "<group>"; };
F8DA09C81396AB690057D0CC /* NearbySpotsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NearbySpotsViewController.m; sourceTree = "<group>"; };
F8DA09CA1396AB690057D0CC /* Spot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Spot.h; sourceTree = "<group>"; };
@ -59,7 +63,7 @@
F8DA09E51396AC220057D0CC /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; };
F8DA09E61396AC220057D0CC /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = SOURCE_ROOT; };
F8DA09E71396AC220057D0CC /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; };
F8E469601395739C00DB05C8 /* AFNetworking iOS Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "AFNetworking iOS Example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
F8E469601395739C00DB05C8 /* AFNetworkingExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AFNetworkingExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
F8E469641395739D00DB05C8 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
F8E469661395739D00DB05C8 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
F8E469681395739D00DB05C8 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
@ -67,10 +71,8 @@
F8E469DE13957DD500DB05C8 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
F8E469E013957DF100DB05C8 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
F8E469E213957DF700DB05C8 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
F8E469E413957E0400DB05C8 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
F8FBFA96142AA237001409DB /* AFHTTPClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFHTTPClient.h; path = ../AFNetworking/AFHTTPClient.h; sourceTree = "<group>"; };
F8FBFA97142AA238001409DB /* AFHTTPClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFHTTPClient.m; path = ../AFNetworking/AFHTTPClient.m; sourceTree = "<group>"; };
FF2B770C140DAC4E00A8DEC2 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -82,7 +84,8 @@
F8E469671395739D00DB05C8 /* Foundation.framework in Frameworks */,
F8E469691395739D00DB05C8 /* CoreGraphics.framework in Frameworks */,
F8E469DF13957DD500DB05C8 /* CoreLocation.framework in Frameworks */,
FF2B770D140DAC4E00A8DEC2 /* libz.dylib in Frameworks */,
F8D0701B14310F4A00653FD3 /* SystemConfiguration.framework in Frameworks */,
F8D0701C14310F4F00653FD3 /* Security.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -151,6 +154,7 @@
F8E469551395739C00DB05C8 = {
isa = PBXGroup;
children = (
F8E469B71395759C00DB05C8 /* Networking Extensions */,
F8E4696A1395739D00DB05C8 /* Classes */,
F8E469ED1395812A00DB05C8 /* Images */,
F8E469931395743A00DB05C8 /* Vendor */,
@ -162,7 +166,7 @@
F8E469611395739C00DB05C8 /* Products */ = {
isa = PBXGroup;
children = (
F8E469601395739C00DB05C8 /* AFNetworking iOS Example.app */,
F8E469601395739C00DB05C8 /* AFNetworkingExample.app */,
);
name = Products;
sourceTree = "<group>";
@ -170,14 +174,12 @@
F8E469631395739D00DB05C8 /* Frameworks */ = {
isa = PBXGroup;
children = (
F8E469E413957E0400DB05C8 /* SystemConfiguration.framework */,
F8E469E213957DF700DB05C8 /* SystemConfiguration.framework */,
F8E469E013957DF100DB05C8 /* Security.framework */,
F8E469DE13957DD500DB05C8 /* CoreLocation.framework */,
F8E469641395739D00DB05C8 /* UIKit.framework */,
F8E469661395739D00DB05C8 /* Foundation.framework */,
F8E469681395739D00DB05C8 /* CoreGraphics.framework */,
FF2B770C140DAC4E00A8DEC2 /* libz.dylib */,
);
name = Frameworks;
sourceTree = "<group>";
@ -185,7 +187,6 @@
F8E4696A1395739D00DB05C8 /* Classes */ = {
isa = PBXGroup;
children = (
F8E469B71395759C00DB05C8 /* Networking Extensions */,
F8DA09C61396AB690057D0CC /* Controllers */,
F8DA09C91396AB690057D0CC /* Models */,
F8DA09CC1396AB690057D0CC /* Views */,
@ -240,9 +241,10 @@
F8E469B71395759C00DB05C8 /* Networking Extensions */ = {
isa = PBXGroup;
children = (
F8D25D1B1396A9DE00CF3BD6 /* AFGowallaAPIClient.h */,
F8D25D1D1396A9DE00CF3BD6 /* AFGowallaAPIClient.m */,
);
name = "Networking Extensions";
path = ..;
sourceTree = "<group>";
};
F8E469ED1395812A00DB05C8 /* Images */ = {
@ -258,9 +260,9 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
F8E4695F1395739C00DB05C8 /* AFNetworking iOS Example */ = {
F8E4695F1395739C00DB05C8 /* AFNetworkingExample */ = {
isa = PBXNativeTarget;
buildConfigurationList = F8E469811395739D00DB05C8 /* Build configuration list for PBXNativeTarget "AFNetworking iOS Example" */;
buildConfigurationList = F8E469811395739D00DB05C8 /* Build configuration list for PBXNativeTarget "AFNetworkingExample" */;
buildPhases = (
F8E4695C1395739C00DB05C8 /* Sources */,
F8E4695D1395739C00DB05C8 /* Frameworks */,
@ -270,9 +272,9 @@
);
dependencies = (
);
name = "AFNetworking iOS Example";
name = AFNetworkingExample;
productName = AFNetworkingExample;
productReference = F8E469601395739C00DB05C8 /* AFNetworking iOS Example.app */;
productReference = F8E469601395739C00DB05C8 /* AFNetworkingExample.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
@ -284,7 +286,7 @@
LastUpgradeCheck = 0420;
ORGANIZATIONNAME = Gowalla;
};
buildConfigurationList = F8E4695A1395739C00DB05C8 /* Build configuration list for PBXProject "AFNetworking iOS Example" */;
buildConfigurationList = F8E4695A1395739C00DB05C8 /* Build configuration list for PBXProject "AFNetworking Example" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
@ -296,7 +298,7 @@
projectDirPath = "";
projectRoot = "";
targets = (
F8E4695F1395739C00DB05C8 /* AFNetworking iOS Example */,
F8E4695F1395739C00DB05C8 /* AFNetworkingExample */,
);
};
/* End PBXProject section */
@ -318,6 +320,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F8DA09D21396ABED0057D0CC /* AFGowallaAPIClient.m in Sources */,
F8DA09D41396ABED0057D0CC /* NearbySpotsViewController.m in Sources */,
F8DA09D51396ABED0057D0CC /* Spot.m in Sources */,
F8DA09D61396ABED0057D0CC /* SpotTableViewCell.m in Sources */,
@ -378,6 +381,9 @@
GCC_DYNAMIC_NO_PIC = NO;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Prefix.pch;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNUSED_PARAMETER = NO;
INFOPLIST_FILE = Info.plist;
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
@ -391,6 +397,9 @@
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Prefix.pch;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNUSED_PARAMETER = NO;
INFOPLIST_FILE = Info.plist;
PRODUCT_NAME = "$(TARGET_NAME)";
VALIDATE_PRODUCT = YES;
@ -401,7 +410,7 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
F8E4695A1395739C00DB05C8 /* Build configuration list for PBXProject "AFNetworking iOS Example" */ = {
F8E4695A1395739C00DB05C8 /* Build configuration list for PBXProject "AFNetworking Example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F8E4697F1395739D00DB05C8 /* Debug */,
@ -410,7 +419,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F8E469811395739D00DB05C8 /* Build configuration list for PBXNativeTarget "AFNetworking iOS Example" */ = {
F8E469811395739D00DB05C8 /* Build configuration list for PBXNativeTarget "AFNetworkingExample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F8E469821395739D00DB05C8 /* Debug */,

View file

@ -23,6 +23,8 @@
#import "AppDelegate.h"
#import "NearbySpotsViewController.h"
#import "AFNetworkActivityIndicatorManager.h"
@implementation AppDelegate
@synthesize window = _window;
@synthesize navigationController = _navigationController;
@ -31,6 +33,8 @@
NSURLCache *URLCache = [[[NSURLCache alloc] initWithMemoryCapacity:1024 * 1024 diskCapacity:1024 * 1024 * 5 diskPath:nil] autorelease];
[NSURLCache setSharedURLCache:URLCache];
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
UITableViewController *viewController = [[[NearbySpotsViewController alloc] init] autorelease];
self.navigationController = [[[UINavigationController alloc] initWithRootViewController:viewController] autorelease];
@ -38,6 +42,7 @@
self.window.backgroundColor = [UIColor whiteColor];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}

View file

@ -64,9 +64,9 @@
[mutableParameters setValue:[NSString stringWithFormat:@"%1.7f", location.coordinate.longitude] forKey:@"lng"];
}
[[AFGowallaAPIClient sharedClient] getPath:urlString parameters:mutableParameters success:^(id response) {
[[AFGowallaAPIClient sharedClient] getPath:urlString parameters:mutableParameters success:^(id object) {
NSMutableArray *mutableRecords = [NSMutableArray array];
for (NSDictionary *attributes in [response valueForKeyPath:@"spots"]) {
for (NSDictionary *attributes in [object valueForKeyPath:@"spots"]) {
Spot *spot = [[[Spot alloc] initWithAttributes:attributes] autorelease];
[mutableRecords addObject:spot];
}
@ -74,7 +74,7 @@
if (block) {
block([NSArray arrayWithArray:mutableRecords]);
}
} failure:^(NSError *error) {
} failure:^(NSHTTPURLResponse *response, NSError *error) {
if (block) {
block([NSArray array]);
}