Working with NSURLSession: AFNetworking 2.0
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.
在之前的一系列教程当中,我们已经仔细的分析了 NSURLSession 的 API,他是 iOS 7 以及 OS X 新引入的处理网络链接的方法。如今,处理网络越来越简单,小白都能轻易上手了,这得益于 NSURLSession 的帮助哦,亲。虽然小白都能整明白网络是怎么回事,是否意味着不需要使用开源库 AFNetworking 了呢? AFNetworking 2.0 到底有着怎样的特性呢?在这最后的一期教程当中,哥来引领你们,进行 AFNetworking 2.0 与 NSURLSession 之间的纵深比较。
Introduction (介绍)
By all accounts, AFNetworking is about as mainstream as it gets.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.
不管怎样,AFNetworking 都是一个传说。
正如 Mattt Thompson 在 NSHipster 上指出的,AFNetworking 实际上已经成为了 Cocoa 应用中不可或缺的一个开源库。当下还在不停的维护着,这个开源库已经获得了超过10,000人的支持,被fork了将近3,000多次。
如果,你还没听过 AFNetworking
(哥真的鄙视你-_-!!),想了解一下他发展的历史以及一些牛逼的特性,这样的话,哥建议你读一下 Mattt 的博文 AFNetworking 2.0 on
NSHipster 。 在今天你看的这篇博文中,我将重点聚焦在两个方面,AFNetworking 2.0
有哪些新的特性,它与 NSURLSession API 之间到底有啥区别。你应该问一下你自己:“我是否还要用 AFNetworking 配合
NSRULSession 来处理网络呢?”那就是哥要回到你的问题。
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.
在我们进一步了解 AFNetworking 2.0 之前,知道这个开源库有着怎样的新的环境要求非常重要。正如他的版本号标示的那样子,AFNetworking 2.0 比 AFNetworking 1.x 有着更严格的限制条件,它有着许多全新的架构级的改变,和以前已经面目全非了。也就是说,你不要手贱把以前的 AFNetworking 1.x 的项目升级到 AFNetworking 2.0,否则会出现很多的警告,如果你确实想升级一下,恩,migration guide 这个指南应该是你的菜。
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 AFURLRequestSerialization
and
AFURLResponseSerialization
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.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
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.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
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.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
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.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
//
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.
[翻译] Working with NSURLSession: AFNetworking 2.0(持续更新),布布扣,bubuko.com