-
Notifications
You must be signed in to change notification settings - Fork 0
AFNetworking 2.0 Migration Guide
AFNetworking 2.0 is the next 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.
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.
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 <NSURLResponseSerialization>.
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 <NSURLRequestSerialization>.
Both <NSURLRequestSerialization> & <NSURLResponseSerialization> 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 *)errorAFNetworking 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, AFJSONSerializer 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.
NSURL *URL = [NSURL URLWithString:@"http://example.com/foo.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
initWithRequest:request];
operation.responseSerializer = [AFJSONSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"%@", responseObject);
} failure:nil];
[operation start];AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONSerializer 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.
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).
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, AFHTTPClient now inherits from AFURLSessionManager (previously NSObject), adding support for session tasks to its existing request operations functionality. 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:
- (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- (NSURLSessionDataTask *)GET:(NSString *)URLString
parameters:(NSDictionary *)parameters
success:(void (^)(NSURLSessionDataTask *, id))success
failure:(void (^)(NSError *))failure
- (NSURLSessionDataTask *)HEAD:(NSString *)URLString
parameters:(NSDictionary *)parameters
success:(void (^)(NSURLSessionDataTask *))success
failure:(void (^)(NSError *))failure
- (NSURLSessionDataTask *)POST:(NSString *)URLString
parameters:(NSDictionary *)parameters
success:(void (^)(NSURLSessionDataTask *, id))success
failure:(void (^)(NSError *))failure
- (NSURLSessionDataTask *)POST:(NSString *)URLString
parameters:(NSDictionary *)parameters
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData>))block
success:(void (^)(NSURLSessionDataTask *, id))success
failure:(void (^)(NSError *))failure
- (NSURLSessionDataTask *)PUT:(NSString *)URLString
parameters:(NSDictionary *)parameters
success:(void (^)(NSURLSessionDataTask *))success
failure:(void (^)(NSError *))failure
- (NSURLSessionDataTask *)PATCH:(NSString *)URLString
parameters:(NSDictionary *)parameters
success:(void (^)(NSURLSessionDataTask *))success
failure:(void (^)(NSError *))failure
- (NSURLSessionDataTask *)DELETE:(NSString *)URLString
parameters:(NSDictionary *)parameters
success:(void (^)(NSURLSessionDataTask *))success
failure:(void (^)(NSError *))failureAnother 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.
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 compltionBlock.
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: AddsimageResponseSerializerproperty, which makes it easy to automatically resize or apply a filter to images loaded remotely to an image view. For example,CIImageSerializercould be used to apply specified Core Image filters to the response image before being displayed. -
UIButton+AFNetworking(New): Similar toUIImageView+AFNetworking, loadsimageandbackgroundImagefrom remote source. -
UIActivityIndicatorView+AFNetworking(New): Automatically start and stop aUIActivityIndicatorViewaccording 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.
Perhaps the most exciting addition in AFNetworking 2.0 is its first-class support for realtime networking using Rocket.
Rocket is a technique for building real-time functionality on top of REST web services that leverages web standards like Server-Sent Events and JSON Patch.
AFEventSource is an Objective-C implementation of the EventSource DOM API. A persistent HTTP connection is opened to a host, which streams events to the event source, to be dispatched to listeners. Messages streamed to the event source formatted as JSON Patch documents are translated into arrays of AFJSONPatchOperation objects. These patch operations can be applied to the persistent data set fetched from the server.
NSURL *URL = [NSURL URLWithString:@"http://example.com"];
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:URL];
[client GET:@"/resources" parameters:nil success:^(NSHTTPURLResponse *response, id responseObject) {
[resources addObjectsFromArray:responseObject[@"resources"]];
[client SUBSCRIBE:@"/resources" usingBlock:^(NSArray *operations, NSError *error) {
for (AFJSONPatchOperation *operation in operations) {
switch (operation.type) {
case AFJSONAddOperationType:
[resources addObject:operation.value];
break;
default:
break;
}
}
} error:nil];
} failure:nil];