AFNetworking 2.0 Migration Guide

Etienne Martin edited this page Jul 31, 2014 · 19 revisions

AFNetworking 2.0 is the latest major release of AFNetworking, a delightful networking library for iOS & Mac OS X. As a major release, following Semantic Versioning conventions, 2.0 introduces several API-breaking changes with its new architecture, which adds support for NSURLSession and introduces a new serialization-based approach to content negotiation.

This guide is provided in order to ease the transition of existing applications using AFNetworking 1.X to the latest APIs, as well as explain the design and structure of new and changed functionality.

New Requirements: iOS 6, Mac OS X 10.8, & Xcode 5

AFNetworking 2.0 officially supports iOS 6+, Mac OS X 10.8+, and Xcode 5. If you'd like to use AFNetworking in a project targeting a base SDK of iOS 5, or Mac OS X 10.7, use the latest tagged 1.x release. For iOS 4.3 and Mac OS X 10.6 support, use the latest tagged 0.10.x release.

Serialization

One of the most significant changes in AFNetworking 2.0 is its new architecture for content negotiation and serialization. Previously, response validation and serialization was delegated to AFHTTPRequestOperation and its subclasses, with content-specific logic scattered throughout implementations for setCompletionBlockWithSuccess:failure: and other properties. In 2.0, all of this logic is encapsulated in a serializer object that conforms to <AFURLResponseSerialization>.

The concept of serialization is also extended to requests, as a way to decouple request factory functionality from AFHTTPClient in previous versions, such as default headers, authentication, and URL query string parameter serialization. Now, these features are encapsulated in a serializer object that conforms to <AFURLRequestSerialization>.

Both <AFURLRequestSerialization> & <AFURLResponseSerialization> are lightweight protocols, with a single method each:

- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
                               withParameters:(NSDictionary *)parameters
                                        error:(NSError *__autoreleasing *)error

- (id)responseObjectForResponse:(NSURLResponse *)response
                           data:(NSData *)data
                          error:(NSError *__autoreleasing *)error

AFNetworking 2.0 comes with a base set of serializations for content types like JSON, XML, property lists, and images. Each of these serializers inherit from a common superclass, AFHTTPSerializer, which serves as a concrete implementation of both <AFURLRequestSerialization> & <AFURLResponseSerialization>, providing a default URL query string parameter serialization scheme and default headers for requests, and MIME type and status code validation for responses.

For requests with methods not included in HTTPMethodsEncodingParametersInURI, AFJSONResponseSerializer will encode parameters as JSON in the HTTP body, setting the Content-Type header accordingly. Likewise, AFPropertyListSerializer will encode parameters and set the request header for plist content.

AFHTTPRequestOperationManager and AFHTTPSessionManager both have requestSerializer and responseSerializer properties. AFHTTPRequestOperation adds a responseSerializer property as well, which makes it the preferred request operation class for requests of any content type, rather than being merely a superclass.

requestSerializer is responsible for adding authentication and other shared headers to requests created with -requestWithMethod:URLString:parameters:.

responseSerializer is responsible for serializing a response and its associated data into a response object, or generating an error if the response is invalid. Serialization occurs in the completion block of request operations and session tasks.

AFHTTPRequestOperation Example

NSURL *URL = [NSURL URLWithString:@"http://example.com/foo.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
                                     initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"%@", responseObject);
} failure:nil];
[operation start];

AFHTTPRequestOperationManager Example

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager GET:@"http://example.com/foo.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"%@", responseObject);
} failure:nil];

Response serializers can also be chained, using AFCompoundSerializer. Compound serializers consult each component serializer in order, until it finds one that successfully performs responseObjectForResponse:data:error: without generating an error. If a request operation or task, for example, wanted to be able to handle both JSON and XML responses using a single code path, this can be accomplished by setting a compound serializer with XML and JSON serializer components as the responseSerializer of the HTTP request operation or HTTP client. By default, AFHTTPRequestOperationManager and AFHTTPSessionManager have JSON serializers.

NSURLSession & AFURLSessionManager

New in iOS 7 & Mac OS X 10.9 Mavericks, NSURLSession replaces NSURLConnection as the preferred class for network transfers in the Foundation framework.

Unlike NSURLConnection objects, which each share application-wide settings for session management, cache policies, cookie storage, and URL protocols, NSURLSession objects can configure these all individually. Once a session is initialized with a particular configuration, it can dispatch tasks to fetch data, and upload or download files.

AFNetworking 2.0 introduces AFURLSessionManager, which manages an NSURLSession object based on a specified NSURLSessionConfiguration object, and conforms to <NSURLSessionTaskDelegate>, <NSURLSessionDataDelegate>, <NSURLSessionDownloadDelegate>, and <NSURLSessionDelegate>. Convenience methods to inspect and cancel tasks are provided, as well as block-based callback properties for each delegate method (14 across 4 different protocols).

AFHTTPClient → AFHTTPRequestOperationManager & AFHTTPSessionManager

Let's be honest: AFHTTPClient did way too many things. Request creation, multipart streaming request creation, operation creation, operation management, serialization, batched operations, network reachability...

In 2.0, AFHTTPClient has been split into a few pieces. First, there are now NSURLConnection request operation-backed and NSURLSession task-backed manager classes: AFHTTPRequestOperationManager & AFHTTPSessionManager. All of the other functionality has been split into modules for serialization, security, and network reachability monitoring.

As of 2.0, the HTTP verb convenience methods getPath:parameters:success:failure: have been renamed to GET:parameters:success:failure:, and now initialize, run, and return session data tasks:

AFHTTPClient Convenience Methods (AFNetworking 1.x)

- (void)getPath:(NSString *)URLString
     parameters:(NSDictionary *)parameters
        success:(void (^)(AFHTTPRequestOperation *, id ))success
        failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure

- (void)headPath:(NSString *)URLString
      parameters:(NSDictionary *)parameters
         success:(void (^)(AFHTTPRequestOperation *, id ))success
         failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure

- (void)postPath:(NSString *)URLString
      parameters:(NSDictionary *)parameters
         success:(void (^)(AFHTTPRequestOperation *, id ))success
         failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure

- (void)putPath:(NSString *)URLString
     parameters:(NSDictionary *)parameters
        success:(void (^)(AFHTTPRequestOperation *, id ))success
        failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure

- (void)patchPath:(NSString *)URLString
       parameters:(NSDictionary *)parameters
          success:(void (^)(AFHTTPRequestOperation *, id ))success
          failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure

- (void)deletePath:(NSString *)URLString
        parameters:(NSDictionary *)parameters
           success:(void (^)(AFHTTPRequestOperation *, id ))success
           failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure

AFHTTPRequestOperationManager / AFHTTPSessionManager Convenience Methods (AFNetworking 2.0)

- (NSURLSessionDataTask *)GET:(NSString *)URLString
                   parameters:(NSDictionary *)parameters
                      success:(void (^)(NSURLSessionDataTask *, id))success
                      failure:(void (^)(NSURLSessionDataTask *, NSError *))failure

- (NSURLSessionDataTask *)HEAD:(NSString *)URLString
                    parameters:(NSDictionary *)parameters
                       success:(void (^)(NSURLSessionDataTask *))success
                       failure:(void (^)(NSURLSessionDataTask *, NSError *))failure

- (NSURLSessionDataTask *)POST:(NSString *)URLString
                    parameters:(NSDictionary *)parameters
                       success:(void (^)(NSURLSessionDataTask *, id))success
                       failure:(void (^)(NSURLSessionDataTask *, NSError *))failure

- (NSURLSessionDataTask *)POST:(NSString *)URLString
                    parameters:(NSDictionary *)parameters
     constructingBodyWithBlock:(void (^)(id <AFMultipartFormData>))block
                       success:(void (^)(NSURLSessionDataTask *, id))success
                       failure:(void (^)(NSURLSessionDataTask *, NSError *))failure

- (NSURLSessionDataTask *)PUT:(NSString *)URLString
                   parameters:(NSDictionary *)parameters
                      success:(void (^)(NSURLSessionDataTask *, id))success
                      failure:(void (^)(NSURLSessionDataTask *, NSError *))failure

- (NSURLSessionDataTask *)PATCH:(NSString *)URLString
                     parameters:(NSDictionary *)parameters
                        success:(void (^)(NSURLSessionDataTask *))success
                        failure:(void (^)(NSURLSessionDataTask *, NSError *))failure

- (NSURLSessionDataTask *)DELETE:(NSString *)URLString
                      parameters:(NSDictionary *)parameters
                         success:(void (^)(NSURLSessionDataTask *, id))success
                         failure:(void (^)(NSURLSessionDataTask *, NSError *))failure

Another important change from AFHTTPClient is that baseURL is no longer required during manager initialization. When specified, a baseURL will provide automatic network reachability change notifications, and allow for relative paths to be passed to HTTP verb convenience methods. Without a baseURL, network reachability status monitoring will not be available, and full URL strings need to be passed to convenience methods.

AFHTTPRequestOperation

As mentioned previously, the new serialization architecture of AFNetworking 2.0 means that AFHTTPRequestOperation will be used directly, rather than being a mere jumping-off point for content-specific request operation subclasses.

In addition to its responseSerializer property, AFHTTPRequestOperation adds a completionQueue and a completionGroup property. completionQueue replaces the previous successQueue and failureQueue, and determines where the completion block will dispatch to after serializing its response in the background. completionGroup and the corresponding use of dispatch_group_* rather than dispatch_* allows for functionality to be triggered once all operation callbacks have finished firing. For example, this change allows for the completion block of a batch of operations to be run after all of the operations in the batch have finished running their completionBlock.

UIKit Extensions

All of the UIKit categories in AFNetworking 2.0 have been extracted and expanded, with several new additions to the list:

  • AFNetworkActivityIndicatorManager: Automatically start and stop the network activity indicator in the status bar as request operations and tasks begin and finish loading.
  • UIImageView+AFNetworking: Adds imageResponseSerializer property, which makes it easy to automatically resize or apply a filter to images loaded remotely to an image view. For example, CIImageSerializer could be used to apply specified Core Image filters to the response image before being displayed.
  • UIButton+AFNetworking (New): Similar to UIImageView+AFNetworking, loads image and backgroundImage from remote source.
  • UIActivityIndicatorView+AFNetworking (New): Automatically start and stop a UIActivityIndicatorView according to the state of a specified request operation or session task.
  • UIProgressView+AFNetworking (New): Automatically track the upload or download progress of a specified request operation or session task.
  • UIWebView+AFNetworking (New): Provides a more sophisticated API for loading URL requests, with support for progress callbacks and content transformation.