-
Notifications
You must be signed in to change notification settings - Fork 0
AFNetworking FAQ
While NSURLConnection provides +sendAsynchronousRequest:queue:completionHandler: and +sendSynchronousRequest:returningResponse:error:, there are many benefits to using AFNetworking:
-
AFURLConnectionOperationand its subclasses inherit fromNSOperation, which allows requests to be cancelled, suspended / resumed, and managed by anNSOperationQueue. -
AFURLConnectionOperationalso allows you to easily stream uploads and downloads, handle authentication challenges, monitor upload and download progress, and control the caching behavior or requests. -
AFHTTPRequestOperationand its subclasses distinguish between successful and unsuccessful requests based on HTTP status codes and content type. - AFNetworking includes media-specific request operations that transform
NSDatainto more useable formats, like JSON, XML, images, and property lists. -
AFHTTPClientprovides a convenient interface to interact with web services, including default headers, authentication, network reachability monitoring, batched operations, query string parameter serialization, and multipart form requests. -
UIImageView+AFNetworkingadds a convenient way to asynchronously loads images.
AFNetworking takes advantage of the caching functionality already provided by NSURLCache and any of its subclasses.
We recommend you try out Pete Steinberger's fork of SDURLCache, which provides disk caching, which is not otherwise implemented by NSURLCache on iOS. You may find it useful to set ignoreMemoryOnlyStoragePolicy to YES for the SDURLCache instance, which will ensure that images will be cached to disk more consistently for offline use (which, as reported in the SDURLCache README, iOS 5 supports, but only for http, so it still remains a good option if you want to support iOS 4 or https)
Uploading a file is really just constructing an HTTP multi-part form body for a URL request.AFHTTPClient provides several helper functions that make this easy.
To create the request object, you would do something like:
NSData *imageData = UIImagePNGRepresentation(image);
NSURLRequest *request = [client multipartFormRequestWithMethod:@"POST" path:@"/upload" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData mimeType:@"image/png" name:@"avatar"];
}];You could then pass request into any request operation, like AFJSONRequestOperation -JSONRequestOperationWithRequest:success:failure:.
Use the outputStream property of AFURLConnectionOperation or its subclasses, setting it to an NSOutputStream that streams to a file at a specified path:
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:@"download.zip" append:NO];This is especially useful when you're downloading anything relatively large (more than a few MB), since the contents of the file will be streamed directly to the file, rather than being stored in memory.
AFNetworking does not include any mechanisms for gzip compression, but you can easily compress data manually or by using libraries like Godzippa (you will likely need to add the zlib library in your build target). Simply take the HTTPBody from a NSMutableURLRequest, compress the data, and re-set it before creating the operation using the request. Gzip decompression from server responses is already built into AFNetworking, as NSURLConnection will automatically decompress responses with the Content-Encoding: gzip HTTP header.
As of AFNetworking 1.0RC1, AFURLConnectionOperation has a setShouldExecuteAsBackgroundTaskWithExpirationHandler: method that can be used to have operations continue when an app is dismissed and enters the background:
[self setShouldExecuteAsBackgroundTaskWithExpirationHandler:^{
// Clean up anything that needs to be handled if the request times out
// It may be useful to initially check whether the operation finished or was cancelled
}];If you're using AFHTTPClient, set the parameterEncoding property to AFJSONParameterEncoding. Any method on that HTTP client with a parameters argument will now encode the passed object into a JSON string and set the HTTP body and Content-Type header appropriately.
Otherwise, you can do this manually by adding the header Content-Type: application/json, and setting the body of your request to a JSON string.
AFURLConnectionOperation provides the methods setUploadProgressBlock: and setDownloadProgressBlock:. Each method takes a single parameter, which is a block that will be executed periodically during the lifetime of the request. The block has no return type and takes 3 arguments: the number of bytes read or written for this callback, the total number of bytes read or written so far, and the total number of bytes expected to be read or written.
If you wanted to update a progress bar, you could set the respective progress block to set the progress amount to total number bytes read or written divided by the expected number, normalized between 0.0 and 1.0. UI updates based on this value will update asynchronously as the request is being made.
All request operations have the inputStream and outputStream property. To download data as its sent from the server, set the outputStream property with an NSOutputStream object, To upload the contents of a file, for instance, by streaming it into the body of a request, set inputStream with an NSInputStream object. To stream multiple files in a given request, build a multipart form request, serialize to a temp file on disk, and stream that file.
The short answer is: you don't. Access the responseObject properties as needed once the operation is finished.
If you are using batched operations, or chaining operations in a complex way, you may run into issues caused by there not being any guarantees of when and how long an operation's completionBlock is run. Keep in mind that the default completionBlocks often do nothing more than serialize response objects, which are accessible as a property on the operation. So, for example, if you wish to create a set of records from the JSON of multiple operations in a batch, you could omit completionBlocks for each operation, and instead enumerate each of the finished operations in the batch callback and access the responseJSON property directly.
These content types are only returned as the response object for requests when 1) the HTTP client has registered the appropriate AFHTTPRequestOperation subclass with -registerHTTPOperationClass:, and 2) the request Accept HTTP header is appropriate for the content type requested. Not doing this may result in getting an NSData instance of the success or failure callback blocks of methods like getPath:parameters:success:failure.
So to work with JSON data, for example, do [client registerHTTPOperationClass:[AFJSONRequestOperation class]] and [client setDefaultHeader:@"Accept" value:@"application/json"] when initializing the HTTP client.
Use AFHTTPClient -enqueueBatchOfHTTPRequestOperationsWithRequests:progressBlock:completionBlock: or -enqueueBatchOfHTTPRequestOperations:progressBlock:completionBlock: to batch a series of requests together, specifying a callback for when all of the requests have finished. As mentioned in the question about waiting for completion blocks to finish, you may not want to set completion blocks on each individual operation, and instead access the response object properties directly in the batch completion block.
Yes. Check out AFOAuth2Client.
Use NSURLProtocol to intercept requests before they hit the network, and return canned responses using local data. More information about this technique can be found in this blog post by Claus Broch. You may also want to try OHHTTPStubs, which provides a block-based interface around these patterns.
Is AFNetworking compatible with ARC?
Yes--projects with Automatic Reference Counting (ARC) enabled can use AFNetworking. However, since AFNetworking's codebase does not yet use ARC, you will need to add compiler flags to get everything working. 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.
We are holding off on transitioning the codebase to ARC until a majority of developers have made the switch themselves. This decision is made in the hopes of not only maximizing compatibility of the library, but to keep the codebase accessible to programmers who are not yet familiar with ARC. Rather than duplicating work across branching, or complicating matters with pre-processor macros, AFNetworking will make the transition all at once, which will be tagged as a new major release. We expect to make this transition sometime in early 2012.
AFNetworking will continue to be released and actively maintained by its creators and contributors under the MIT License.
No matter what happens to Gowalla, AFNetworking is here to stay.
The "AF" in AFNetworking stands for "Alamofire", which is the former name of the company known today as Gowalla. Alamofire Inc. was named after the Alamo Fire, a hybrid of the Bluebonnet--Texas' state flower.
Using AF is also a nod to the "NS" prefix used in Apple's Foundation framework, which harkens back to its NeXTSTEP roots.