AFN框架学习

5,418 阅读4分钟

在了解AFN框架之前,先明白NSURLSession是什么

1. NSURLSession

NSURLSession是苹果官方提供的一套URL加载系统(URL Loading System),提供了通过URL获取资源的能力,通过标准https协议或其他自定协议。

该框架主要包含几个部分:

  • URLSession:用来管理一组有关联性的网络传输任务
  • URLSessionTask:一个网络传输任务,比如下载一个数据,需要通过URLSession执行

关联结构如下图所示:

Figure showing two scenarios, default browsing and private browsing, each with a URL Session creating multiple URL Session Tasks. In the default browsing case, the URL Session contains a default configuration. In the private browsing case, it contains an ephemeral configuration.

NSURLSession的使用也相当简单

Figure showing a URL Session creating a URL Session Data Task. The task then sends the original request, retrieved data, or an error to the completion handler.

最简单的使用方法

  1. 通过NSURLSessionshareInstance获取单例对象
  2. 创建一个URLSessionDataTask对象,传入url
  3. 调用resume开始网络请请求

请求完成后会进行回调,有两种方式

  1. 在创建URLSessionDataTask方法时传入的completeHandler进行回调
  2. 实现相关的delegate,通过delegate方法回调,参考下图

Figure showing a URLSession creating a URLSessionDataTask. The session calls back to the delegate with progress updates, retrieved data, authentication challenges, etc.

总体来说,NSURLSession的使用还是比较简单的,在功能简单时,直接使用没什么问题,但当业务复杂的时候,必然需要进行一些封装,AFNetworking的出现就提供了更丰富的接口设计和良好的扩展能力。

2. AFNetworking

2.1 有哪些特点?

AFNetworking框架非常强大,它基于NSURLSession框架封装,其特点如下:

  • 系统接口封装:封装了与session、task创建、交互等细节
  • 使用方便:使用者仅通过一次方法调用即可完成一次网络请求调用
  • 可扩展性:可扩展的请求封装和回包封装
  • 丰富的接口设计
    • 提供通知、block等多种形式的回调
    • 对HTTP请求的封装
  • 对UIKit进行扩展

2.2 整体架构设计

类图

AFNetworking的整体架构比较简单,最核心的类就是AFURLSessionManager,可以先看下整体类图:

关键类说明

  • AFURLSessionManager
    • 内部创建和管理NSURLSession对象,实现了NSURLSession的相关delegate回调,根据不同的task找到对应的delegate处理后续逻辑
    • 对外暴露了创建dataTask的一系列接口,用于使用者进行网络请求,使用者主要关注NSURLRequest的创建和回调block的实现
  • AFHTTPSessionManager
    • AFURLSessionManager的子类,主要目的是方便构造HTTP请求,如GET、POST等,这个接口对于使用http协议访问的使用者会更方便一些
  • AFURLSessionManagerTaskDelegate
    • 在AFURLSessionManager内部实现,主要是用于与内部所创建的task绑定,记录请求过程中的进度、数据等,最后回调到使用者
  • AFURLResponseSerialization
    • 回包序列化协议,提供唯一接口responseObject,通过传入response、data、error对象,解析成对应的数据
    • 实现类主要以数据维度区分,例如解析json数据、解析XML数据、解析图片数据
  • AFURLRequestSerialization
    • 请求序列化对象,提供唯一接口requestBySerializingRequest:withParameters:error,用于创建一个请求包含了指定参数的request
    • 它的实现类AFHTTPRequestSerializer提供了HTTP请求头中常用的一些参数设置,例如是否允许蜂窝网络、缓存策略等,使用者可以通过参数快速修改http请求头中的数据,以及通过接口parameters提供自定义的参数
    • sessionManager持有该对象,使用者可自行实现该接口从而实现不同的行为策略

时序图

AFNetworking类图-时序图

请求创建的过程:

  1. 调用httpSessionManager的GET接口,开始触发协议请求
  2. httpSessionManager内部会通过requestSerializer创建一个request对,在调用基类的dataTask接口获取一个dataTask
  3. 基类urlSessionManager通过内部的session对象创建dataTask,同时会创建一个对应的taskDelegate,将task与taskDelegate绑定起来,返回dataTask
  4. 使用者调用resume开始请求流程

请求回包后流程:

  1. 请求回来后,首先由session对象通过delegate回调到urlSessionManager中
  2. urlSessionManager收到delegate后,会通过block回调到使用者,同时也会找到task对应的taskDelegate,处理相关逻辑,如更新进度、数据更新
  3. 当收到didComplete回调后,taskDelegate会通过responseSerializer处理回包数据,转换成对应的格式,最终通过最开始传进来的completeBlock回调到上层

小结

总体来说,AFN的代码结构设计不复杂,其中一些设计巧妙之处:

  1. 通过RequestSerialization和ResponseSerialization策略模式,可以让我们非常容易控制请求头的生成和回包的处理
  2. taskDelegate和task绑定的机制,将不同task的事件处理隔离开

同时,虽然整体结构很简单,但AFN作为一个广受好评的开源框架,其代码实现考虑的非常全面,从多线程的处理、接口设计、一些基本请求serializaer类诸如JSON、XML的实现、UIKIt的扩展等,基本覆盖了日常开发使用的方方面面,足以见得其用心之处。

在具体到比较复杂的业务场景的使用,可以进行一定程度的封装,比如继承AFHttpSessionManager,将请求头的默认参数如全局公用的UserAgent、通用域名等封装起来,以及一些基本的日志、上报等能力封装,能够让业务开发更方便简单。