Skip to content

Getting Started with AFNetworking

Mattt Thompson edited this page Aug 11, 2013 · 13 revisions

This is a guide to help developers get up to speed with AFNetworking. It is geared primarily towards anyone who is new to Mac or iOS development, or has not worked extensively with 3rd-party libraries before.

These step-by-step instructions are written for Xcode 4.2, using either the iOS 5 or Mac OS 10.7 SDK. If you are using a previous version of Xcode, you may want to update before starting.

For an even easier way to get started with AFNetworking in a new project, check out the AFNetworking Xcode Project Template.

Step 1: Download CocoaPods

CocoaPods is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like AFNetworking in your projects.

CocoaPods is distributed as a ruby gem, and is installed by running the following commands in Terminal.app:

$ sudo gem install cocoapods
$ pod setup

Depending on your Ruby installation, you may not have to run as sudo to install the cocoapods gem.

Step 2: Create a Podfile

Project dependencies to be managed by CocoaPods are specified in a file called Podfile. Create this file in the same directory as your Xcode project (.xcodeproj) file:

$ edit Podfile
platform :ios, '5.0'
pod 'AFNetworking', '~> 1.3.2'

Step 3: Install Dependencies

Now you can install the dependencies in your project:

$ pod install

From now on, be sure to always open the generated Xcode workspace (.xcworkspace) instead of the project file when building your project:

$ open App.xcworkspace

Step 4: Dive In!

At this point, everything's in place for you to start using AFNetworking. Just #import the headers for the classes you need and get to it!

Don't know where to start, exactly? Well, that really depends on what your app does. Listed below are a few common tasks, with an explanation of how to use AFNetworking to accomplish them.

Download and Parse JSON

AFJSONRequestOperation is the perfect tool for this job. All you need to do is ask it for a particular URL, and it'll give you JSON when it's done:

NSURL *url = [NSURL URLWithString:@"http://httpbin.org/ip"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    NSLog(@"IP Address: %@", [JSON valueForKeyPath:@"origin"]);
} failure:nil];

[operation start];

First, we construct an NSURL object and construct an NSURLRequest object from it. NSURLRequest encapsulates pretty much everything there is for an HTTP request, including url, method (GET, POST, PUT, DELETE, etc.), headers, and the body.

We then pass that url request object into AFJSONRequestOperation +JSONRequestOperationWithRequest:success:failure.

The success and failure parameters take block arguments. Blocks are a relatively new and complex feature in Objective-C, so if you're unfamiliar with them, think about reading up on them. Blocks are objects that contain a specified behavior--code that can be executed later.

In the case of our success and failure callback blocks, we're specifying what should happen after the request finishes. The request happens in the background, without locking up or slowing down the app. Depending on whether the response from the server indicates success (e.g. 200 status code and JSON Content-Type), or failure (e.g. 404 status code or unknown MIME type), the code in the corresponding block will be executed.

You'll notice that the argument for success is ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON). The caret (^) indicates that what follows is part of a block. The other arguments: request, response, and JSON are local variables that are passed into the block. In the block, we can use these values to do things like log the contents of the JSON (like in our example), or do more useful things, like populate an NSArray to update the data source of a UITableView.

After constructing the operation object, we have to start it somehow. In the example, we simply send -start, which kicks off the request and returns immediately.

Another option would be to take advantage of the fact that AFJSONRequestOperation, like all of the request operations in AFNetworking, is a subclass of NSOperation. In combination with NSOperationQueue, you can easily have several requests running concurrently (you have the ability to setting a maximum number of operations to run concurrently to keep your network from getting bogged down).

One last note: in addition to JSON, AFNetworking has a handful of request operations that download data and automatically convert it to things like XML, Images, and Property Lists (http://cocoadocs.org/docsets/AFNetworking/1.3.2/Classes/AFPropertyListRequestOperation.html).

Download and Display Images

AFNetworking makes downloading and setting images as simple as getting an image from the project.

Start by adding #import "UIImageView+AFNetworking" to the top of a controller or a view implementation file. This category adds methods to UIImageView, like:

[imageView setImageWithURL:[NSURL URLWithString:@"…"]];

A longer form of this method also allow you to set a placeholder image while the image is downloading.

Use this anytime you need to load a remote image from the server.

Interact with an API, Web Service, or Application

Chances are pretty good that most if not all of the network requests you make are to a single API or web service, like a Rails or Sinatra backend.

If your app talks to a server backend (or a few different ones), then you'll love AFHTTPClient.

AFHTTPClient has everything you need for talking to a web API. It stores a base URL, which you can request relative paths to (e.g. base URL: http://example.com + relative path: /users = http://example.com/users). You can store a common set of header for things like authentication, content type, and language preferences, which will be added to any request you make with the client. Best of all, it will even automatically figure out how to parse your server response, so JSON requests give you JSON objects, XML requests give you parser objects, etc.

Here are some guidelines on how best to use AFHTTPClient:

  • Create a subclass for each service endpoint you hit. For instance, if you're writing a social network aggregator, you might want a client for Twitter, one for Facebook, another for Instragram, and so on.
  • In HTTP client subclasses, create a class method that returns a shared singleton instance. This way, you can configure and use a single client to use throughout the entire app.
  • Want to upload a file? Check out -multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:. In the block, send the multi-part form data builder -appendPartWithFileData:name:fileName:mimeType:
  • If you need to send request parameters as JSON, simply set the parameterEncoding property to AFJSONParameterEncoding.
  • If you need to configure or hold a reference to a request operation before it's enqueued into the client's operation queue, use -HTTPRequestOperationWithRequest:success:failure. Likewise with the URL request object, use requestWithMethod:path:parameters.

A good example of an AFHTTPClient subclass can be found in the example project: AFAppDotNetAPIClient. Use it as a starting point for your own client.

Next Steps

You can find even more articles like this one on the wiki. You'll also want to keep a link to the documentation handy while you're working on your app.