AFNetworking 2.0Mattt Zihan Xu 🚩🌱

AFNetworking 是当前 iOS 和 OS X 开发中最广泛使用的开源项目之一。它帮助了成千上万叫好又叫座的应用,也为其它出色的开源库提供了基础。这个项目是社区里最活跃、最有影响力的项目之一,拥有 8700 个 star、2200 个 fork 和 130 名贡献者。

从各方面来看,AFNetworking 几乎已经成为主流。

但你有没有听说过它的新版呢? AFNetworking 2.0

这一周的 NSHipster:独家揭晓 AFNetworking 的未来。

声明:NSHipster 由 AFNetworking 的作者 撰写,所以这并不是对 AFNetworking 及它的优点的客观看法。你能看到的是个人关于 AFNetworking 目前及未来版本的真实看法。

AFNetworking 的大体思路

始于 2011 年 5 月,AFNetworking 作为一个已死的 LBS 项目中对 Apple 范例代码的延伸,它的成功更是由于时机。彼时 ASIHTTPRequest 是网络方面的主流方案,AFNetworking 的核心思路使它正好成为开发者渴求的更现代的方案。

NSURLConnection + NSOperation

NSURLConnection 是 Foundation URL 加载系统的基石。一个 NSURLConnection 异步地加载一个 NSURLRequest 对象,调用 delegate 的 NSURLResponse / NSHTTPURLResponse 方法,其 NSData 被发送到服务器或从服务器读取;delegate 还可用来处理 NSURLAuthenticationChallenge、重定向响应、或是决定 NSCachedURLResponse 如何存储在共享的 NSURLCache 上。

NSOperation 是抽象类,模拟单个计算单元,有状态、优先级、依赖等功能,可以取消。

AFNetworking 的第一个重大突破就是将两者结合。AFURLConnectionOperation 作为 NSOperation 的子类,遵循 NSURLConnectionDelegate 的方法,可以从头到尾监视请求的状态,并储存请求、响应、响应数据等中间状态。

Blocks

iOS 4 引入的 block 和 Grand Central Dispatch 从根本上改善了应用程序的开发过程。相比于在应用中用 delegate 乱七八糟地实现逻辑,开发者们可以用 block 将相关的功能放在一起。GCD 能够轻易来回调度工作,不用面对乱七八糟的线程、调用和操作队列。

更重要的是,对于每个 request operation,可以通过 block 自定义 NSURLConnectionDelegate 的方法(比如,通过 setWillSendRequestForAuthenticationChallengeBlock: 可以覆盖默认的 connection:willSendRequestForAuthenticationChallenge: 方法)。

现在,我们可以创建 AFURLConnectionOperation 并把它安排进 NSOperationQueue,通过设置 NSOperation 的新属性 completionBlock,指定操作完成时如何处理 response 和 response data(或是请求过程中遇到的错误)。

序列化 & 验证

更深入一些,request operation 操作也可以负责验证 HTTP 状态码和服务器响应的内容类型,比如,对于 application/json MIME 类型的响应,可以将 NSData 序列化为 JSON 对象。

从服务器加载 JSON、XML、property list 或者图像可以抽象并类比成潜在的文件加载操作,这样开发者可以将这个过程想象成一个 promise 而不是异步网络连接。

介绍 AFNetworking 2.0

AFNetworking 胜在易于使用和可扩展之间取得的平衡,但也并不是没有提升的空间。

在第二个大版本中,AFNetworking 旨在消除原有设计的怪异之处,同时为下一代 iOS 和 OS X 应用程序增加一些强大的新架构。

动机

演员阵容

NSURLConnection 组件 (iOS 6 & 7)

NSURLSession 组件 (iOS 7)


总的来说:为了支持新的 NSURLSession API 以及旧的未弃用且还有用的 NSURLConnection,AFNetworking 2.0 的核心组件分成了 request operation 和 session 任务。AFHTTPRequestOperationManagerAFHTTPSessionManager 提供类似的功能,在需要的时候(比如在 iOS 6 和 7 之间转换),它们的接口可以相对容易的互换。

之前所有绑定在 AFHTTPClient的功能,比如序列化、安全性、可达性,被拆分成几个独立的模块,可被基于 NSURLSessionNSURLConnection 的 API 使用。


序列化

AFNetworking 2.0 新构架的突破之一是使用序列化来创建请求、解析响应。可以通过序列化的灵活设计将更多业务逻辑转移到网络层,并更容易定制之前内置的默认行为。

安全性

感谢 Dustin BarkerOliver LettererKevin Harwood 等人做出的贡献,AFNetworking 现在带有内置的 SSL pinning 支持,这对于处理敏感信息的应用是十分重要的。

可达性

AFHTTPClient 解藕的另一个功能是网络可达性。现在你可以直接使用它,或者使用 AFHTTPRequestOperationManager / AFHTTPSessionManager 的属性。

实时性

NSURL *URL = [NSURL URLWithString:@"http://example.com"];
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:URL];
[manager GET:@"/resources" parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
    [resources addObjectsFromArray:responseObject[@"resources"]];

    [manager 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];

UIKit 扩展

之前 AFNetworking 中的所有 UIKit category 都被保留并增强,还增加了一些新的 category。


于是终于要结束 AFNetworking 旋风之旅了。为下一代应用设计的新功能,结合为已有功能设计的全新架构,有很多东西值得兴奋。

旗开得胜

将下列代码加入 Podfile 就可以开始把玩 AFNetworking 2.0 了:

platform :ios, '7.0'
pod "AFNetworking", "2.0.0"

For anyone coming over to AFNetworking from the current 1.x release, you may find the AFNetworking 2.0 Migration Guide especially useful.

对于由 AFNetworking 1.x 版本转移到新版本的用户,你可以找到 AFNetworking 2.0 迁移指南

如果你遇到 bug 或者其它的奇怪的地方,请通过在 GitHub 开启一个问题来帮助我们改进。非常感谢您的帮助。

对于一般的使用问题,请随时 tweet 我 @AFNetworking,或者给我发邮件。


除非另有声明,本文采用知识共享「署名-非商业性使用 3.0 中国大陆」许可协议授权。