Quantcast
Channel: Envato Tuts+ Code - Mobile Development
Viewing all articles
Browse latest Browse all 1836

Working with NSURLSession: AFNetworking 2.0

$
0
0
tag:code.tutsplus.com,2005:PostPresenter/mobile-22651

In the previous installments of this series, we've taken a close look at the NSURLSession API introduced in iOS 7 and OS X Mavericks. Networking on iOS and OS X has become much simpler and more flexible thanks to the NSURLSession API. Does this mean that you should stop using AFNetworking for your networking needs? And what about AFNetworking 2.0, which was introduced a few months ago? In this final installment, I will tell you about AFNetworking 2.0 and how it compares to the NSURLSession API.


Introduction

As Mattt Thompson points out on NSHipster, AFNetworking has become the de facto networking library for Cocoa applications. At the time of writing, the library has surpassed 10,000 stars on GitHub and was forked close to 3,000 times.

If you're new to AFNetworking and would like to read more about its history and features, then I suggest to read Mattt's post about AFNetworking 2.0 on NSHipster. In this article, I'd like to focus on two aspects, what is new in AFNetworking 2.0 and how does it compare to the NSURLSession API . The question you should be asking yourself is "Should I still be using AFNetworking with NSURLSession in my toolbox?" That's the question I plan to answer in this article.


Requirements

Before we take a closer look at what AFNetworking 2.0 has to offer, it's important to know about the library's new requirements. It shouldn't be a surprise that the requirements of AFNetworking 2.0 are stricter than those of AFNetworking 1.x. As its version number indicates, AFNetworking includes breaking changes, which are the result of its new architecture. This also means that migrating a project from AFNetworking 1.x to 2.0 should be done with caution. The migration guide is the ideal place to start if you plan on migrating a project to AFNetworking 2.0.

AFNetworking no longer supports iOS 4.3 and 5. The minimum deployment targets for iOS and OS X are iOS 6 and OS X 10.8 respectively. AFNetworking 2.0 also requires Xcode 5. If you're still using Xcode 4, this may be a good time to make the transition to Xcode 5.


Solid Foundation

AFURLConnectionOperation

As many of you probably know, AFNetworking is built on top of NSURLConnection and NSOperation, which has proven to be a powerful and elegant combination. The result of this combination is AFURLConnectionOperation, an NSOperation subclass that manages an NSURLConnection instance and implements the NSURLConnectionDelegate protocol. Even though this robust foundation remains unchanged in AFNetworking 2.0, it is supplemented by the NSURLSession API, which I'll cover in more detail later.

Separation of Responsibilities

In AFNetworking 1.x, the AFHTTPRequestOperation class was in charge of request and response serialization and validation. This is no longer true in AFNetworking 2.0. The AFHTTPRequestOperation class and its subclasses are no longer directly responsible for serializing and validating requests and responses. This responsibility has been moved to the and protocols. Each protocol declares a single delegate method to handle request and response serialization and validation respectively.

To make your life easier, however, AFNetworking 2.0 ships with AFHTTPRequestSerializer and AFHTTPResponseSerializer as well as a number of subclasses for common content types, such as JSON and XML. To see how this works in practice, let's take a look at an example in which I query the Forecast API. This doesn't look all that different from how you made a request with AFNetworking 1.x. The main difference is that you'll be using the AFHTTPRequestOperation class more often. The AFJSONRequestOperation and AFXMLRequestOperation classes are no longer present in AFNetworking 2.0.

NSString *key = @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"https://api.forecast.io/forecast/%@/37.8267,-122.423", key]];

// Initialize Request Operation
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:[NSURLRequest requestWithURL:URL]];

// Configure Request Operation
[requestOperation setResponseSerializer:[AFJSONResponseSerializer serializer]];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    // Process Response Object

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    // Handle Error
}];

// Start Request Operation
[requestOperation start];

The AFJSONResponseSerializer class inherits from AFHTTPResponseSerializer and should be used for JSON responses. If you need to process XML responses, then AFXMLNResponseSerializer will help you out. For other content types, you need to subclass AFHTTPResponseSerializer.

AFHTTPRequestOperationManager

Another major change in AFNetworking 2.0 is the removal of the AFHTTPClient class, which was in charge of talking to web services. The responsibilities of AFHTTPClient have been split up into a number of classes and protocols. To talk to a web service, you now use AFHTTPRequestOperationManager and AFHTTPSessionManager. Just like AFHTTPRequestOperation, AFHTTPRequestOperationManager and AFHTTPSessionManager delegate serialization of requests and responses to separate objects. Both AFHTTPRequestOperationManager and AFHTTPSessionManager have a requestSerializer and responseSerializer property for this purpose. Let's revisit the above example to see how this works in practice.

NSString *key = @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
NSURL *baseURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://api.forecast.io/forecast/%@/", key]];

// Initialize Request Operation Manager
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:baseURL];

// Configure Request Operation Manager
[manager setResponseSerializer:[AFJSONResponseSerializer serializer]];

// Send Request
[manager GET:@"37.8267,-122.423" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
    // Process Response Object

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    // Handle Error
}];

What About NSURLSession?

AFURLSessionManager

The key question when discussing AFNetworking 2.0 in the light of the NSURLSession API is whether we still need AFNetworking. AFNetworking adds a number of convenience classes and methods to the NSURLSession API and this is only possible thanks to the separation of responsibilities I discussed earlier. The most significant improvement that AFNetworking provides on top of the NSURLSession API are the AFURLSessionManager and AFHTTPSessionManager classes.

The AFURLSessionManager helps you manage an NSURLSession object. Even though I love the NSURLSession API, I have to agree with Mattt that its API is incomplete. The AFURLSessionManager class adds a number of convenience methods that make the NSURLSession API even better. Serialization and validation, for example, are much easier and intuitive with AFNetworking. Just like the AFHTTPRequestOperationManager, instances of AFURLSessionManager have a requestSerializer and responseSerializer property that makes serialization of requests and responses seamless and intuitive.

NSString *key = @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"https://api.forecast.io/forecast/%@/37.8267,-122.423", key]];

// Initialize Session Configuration
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];

// Initialize Session Manager
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:sessionConfiguration];

// Configure Manager
[manager setResponseSerializer:[AFJSONResponseSerializer serializer]];

// Send Request
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
[[manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
    // Process Response Object
}] resume];

I hope you can see the benefit of using AFNetworking in combination with the NSURLSession API. It makes working with the NSURLSession API much more intuitive especially if you're already used to the way AFNetworking 2.0 separates serialization and validation from the actual task or request operation.

AFHTTPSessionManager

AFNetworking 2.0 also incudes a subclass of AFURLSessionManager, AFHTTPSessionManager, which makes interacting with web services a breeze. The AFHTTPSessionManager class includes a number of conveniences methods, such as GET:parameters:success:failure: and POST:parameters:constructingBodyWithBlock:success:failure: that make the migration process from AFHTTPClient to AFHTTPSessionManager easy. Similar methods are also available in the AFHTTPRequestOperationManager class, which I discussed earlier.


Reachability

Reachability is managed by the AFURLRequestOperationManager and AFURLSessionManager classes. When instances of these classes have a valid baseURL, then a reachability manager is automatically instantiated and set up. Of course, it is also possible to explicitly create an instance of the AFNetworkReachabilityManager class.


Icing On The Cake

AFNetworking 2.0 has a number of other features, such as built-in support for SSL pinning and various categories on UIKit classes. Take a look at this example in which I leverage AFNetworking's category on UIProgressView to update a progress view while downloading a remote image.

// Initialize Request
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://cdn.tutsplus.com/mobile/uploads/2014/01/5a3f1-sample.jpg"]];

// Initialize Session Manager
self.sessionManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

// Initialize Download Task
NSURLSessionDownloadTask *downloadTask = [self.sessionManager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
    // Handle Success

} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
    // Handle Failure
}];

[self.progressView setProgressWithDownloadProgressOfTask:downloadTask animated:YES];

[downloadTask resume];

Verdict

If your project doesn't rely on networking, then you won't need all the power and convenience that AFNetworking has to offer. As a matter of fact, I think it's important that every iOS or OS X developer is familiar with NSURLSession and NSURLConnection, because they are key components of the platform.

Even though the NSURLSession API is great and easy to use, the networking APIs provided by the Foundation framework aren't perfect. As Mattt points out, even the NSURLSession API has a few notable gaps. AFNetworking tries to elegantly fill these gaps. The combination of the NSURLSession API and AFNetworking is a marriage made in heaven. It truly is a joy to use.

I really like the NSURLSession API and I hope I've convinced you of its power in this series. However, this doesn't mean that AFNetworking has become obsolete. In my opinion, AFNetworking is the perfect companion of the NSURLSession API. AFNetworking has matured and it is indeed the best and most robust networking library available. Its modular architecture means that you don't need to include every class or category it has to offer. You are free to pick and choose from the components that it includes. AFNetworking supports CocoaPods subspecs, which make this process trivial.


Conclusion

I couldn't be more happy with the second major release of AFNetworking. The library's modularity and separation of responsibilities is what makes it shine in my opinion. It complements the NSURLSession API so well that you won't even notice that you're using AFNetworking. Mattt Thompson and the more than 130 contributors of AFNetworking have done a formidable job. It's good to be a Cocoa developer.

2014-02-03T12:30:26.000Z2014-02-03T12:30:26.000ZBart Jacobshttp://code.tutsplus.com/tutorials/working-with-nsurlsession-afnetworking-20--mobile-22651

Viewing all articles
Browse latest Browse all 1836

Trending Articles