AFN源码分析总结

文章目录

  • AFN源码分析总结:
    • 0. Content-type和MIME type
    • 1. 序列换和反序列化:
    • 2. multipart/form-data:
    • 3. POST编码类型: enctype
    • 4. URL编码: 百分编码: AFPercentEscapedStringFromString:
    • 5. User-Agent:
    • 6. NSError和NSURLError
    • 7. NSJSONReadingOptions和NSJSONWritingOptions
    • 8. NSURLSession:
      • 8.1 NSURLSessionConfiguration:
      • 8.2 NSURLSessionTask
      • 8.3 NSURLSessionDelegate: session-level的代理方法
      • 8.4 NSURLSessionTaskDelegate : task-level面向all的代理方法
      • 8.5 NSURLSessionDataDelegate : task-level面向data和upload的代理方法
      • 8.6 NSURLSession​Download​Delegate : task-level的面向download的代理方法
      • 8.7 NSURLSessionStreamDelegate : task-level的面向stream的代理方法
      • 8.8 NSURLSessionTaskTransactionMetrics(iOS10)
      • 8.9 NSURLSessionTaskMetrics(iOS10)
    • 9. AFURLSessionManager: NSObject
      • 9.1 AFURLSessionManagerTaskDelegate:
      • 9.2 _AFURLSessionTaskSwizzling:
    • 10. AFHttpSessionManager: AFURLSessionManager
    • 11. Serialization:
      • 11.1 AFURLRequestSerialization:
      • 11.2 AFURLResponseSerialization: 是一个协议
    • 12. Additional Functionality:
      • 12.1 AFSecurityPolicy: 请求的认证功能
      • 12.2 AFNetworkReachabilityManager:
    • 13. AFN调用流程分析:

AFN源码分析总结:

0. Content-type和MIME type

AFN默认是json解析
常用类型

  • application/json
  • text/json
  • text/plain
  • text/javascript
  • application/xml
  • text/xml
  • application/x-plist

图片类型

  • image/tiff
  • image/jpeg
  • image/gif
  • image/png
  • image/ico
  • image/x-icon
  • image/bmp
  • image/x-bmp
  • image/x-xbitmap
  • image/x-win-bitmap

万能类型

  • application/octet-stream

文件类型

  • multipart/form-data

AFN源码分析总结_第1张图片

1. 序列换和反序列化:

  1. 序列化: OC对象转化为JSON数据(NSArray, NSDictionary);
  2. 反序列化: JSON数据转化为OC对象;

2. multipart/form-data:

  1. 原因: 最早的post请求不支持文件上传
  2. 方案: multipart/form-data: 用于支持文件上传, 支持向服务器发送二进制数据.

3. POST编码类型: enctype

  1. application/x-www-form-urlencoded: 默认, key1=value1&key2=value2;
  2. multipart/form-data: 一般用于需要文件上传
  3. text/plain, application/json: 传递文本内容

4. URL编码: 百分编码: AFPercentEscapedStringFromString:

  1. URL编码格式采用的是ASCII码,而不是Unicode;
  2. 对于非ASCII字符,需要使用ASCII字符集的超集进行编码得到相应的字节,然后对每个字节执行百分号编码。对于Unicode字符,RFC文档建议使用utf-8对其进行编码得到相应的字节,然后对每个字节执行百分号编码

5. User-Agent:

  1. 访问网站提供你所使用的浏览器类型及版本、操作系统及版本、浏览器内核、等信息的标识.
  2. 用户在上网访问的时候会作为HTTP的包头的一部分向服务器发送,用于识别用户的当前环境.
  3. iOS开发中AFN将设备的一些基本信息获取拼接成字符串封装了进去.

6. NSError和NSURLError

7. NSJSONReadingOptions和NSJSONWritingOptions

8. NSURLSession:

https://blog.csdn.net/kuangdacaikuang/article/details/53397276

  • 整体流程
    NSURL—>NSURLRequest—>NSURLSession(config / delegate / delegateQueue)—>NSURLSessionDataTask
  • 简单实现代码
  1. NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
  2. NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:@“”]];
  3. NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:{}];
  4. [dataTask resume];
  • .h文件分析
  1. 分为初始化部分、属性部分、dataTask部分、uploadTask部分、downloadTask部分、streamTask部分(iOS9).
  2. 两套API: 一套不到block回调的API, 一套带block回调的API(NSURLSession的分类实现);

8.1 NSURLSessionConfiguration:

https://www.jianshu.com/p/9e7e19f9afe5

  • 三种类型的configuratin
  1. defaultSessionConfiguration: 默认的配置会将缓存存储在磁盘上, 并在用户的钥匙串中存储凭据, 还将cookie(默认情况下)存储在共享cookie存储中.
  2. ephemeralSessionConfiguration: 第二种瞬时会话模式不会创建持久性存储的缓存, 短暂会话对于web浏览器和其他类似情况下的私有浏览模式非常理想.
  3. backgroundSessionConfigurationWithIdentifier: 后台会话模式允许程序在后台进行上传下载工作.
  • 三个存储或缓存相关类: NSHTTPCookieStorage, NSURLCredentialStorage, NSURLCache
  • 很多属性等.

8.2 NSURLSessionTask

  • NSURLSessionTask (抽象类,NSURLSessionTaskDelegate)

    • NSURLSessionDataTask (NSURLSessionDataDelegate) 用于建立一个普通连接
      • NSURLSessionUploadTask (NSURLSessionDataDelegate) 用于建立一个上传连接
    • NSURLSessionDownloadTask (NSURLSessionDownloadDelegate) 用于建立一个下载连接
    • NSURLSessionStreamTask (NSURLSessionStreamTaskDelegate) 用于建立一个TCP/IP连接
  • NSURLSessionDelegate

    • NSURLSessionTaskDelegate
      • NSURLSessionDataDelegate
      • NSURLSessionDownloadDelegate
      • NSURLSessionStreamTaskDelegate
  • NSURLSessionTaskState:

  1. NSURLSessionTaskStateRunning: 执行中
  2. NSURLSessionTaskStateSuspended: 挂起
  3. NSURLSessionTaskStateCanceling: 取消
  4. NSURLSessionTaskStateCompleted: 完成

8.3 NSURLSessionDelegate: session-level的代理方法

  1. URLSession: didBecomeInvalidWithError: session遇到错误
  2. URLSession: didReceiveChallenge: completionHandler: 需要认证
  3. URLSessionDidFinishEventsForBackgroundURLSession: 应用进入后台

8.4 NSURLSessionTaskDelegate : task-level面向all的代理方法

  1. 重定向功能: 当请求重定向的时候调用这个方法。我们必须设置一个新的NSURLRequest对象传入completionHandler来重定向新的请求,但是当session是background模式的时候,这个方法不会被调用。
  2. 认证功能: 当请求需要认证的时候调用这个方法.
  3. 新的请求体: 如果请求需要一个新的请求体时,这个方法就会被调用。比如认证失败的时候,我们可以通过这个机会从新认证。
  4. 获取进度: 当我们上传数据的时候,我们可以通过这个代理方法获取上传进度.
  5. 统计信息: 当task的统计信息收集好了以后,调用.
  6. 失败回调: 当一个task出错的时候,会调用这个方法。如果error是nil,也会调用这个方法,表示task完成

8.5 NSURLSessionDataDelegate : task-level面向data和upload的代理方法

  1. 接收消息: 当一个task接收到返回信息。当所有信息都接收完毕以后,completionHandler会被调用
  2. task转换: 当一个datatask转换为一个downloadtask以后会调用; completionHandler允许处理服务器的响应,才会继续接收服务器返回的数据.
  3. 流数据处理: 当一个datatask转换为一个streamTask以后会调用;
  4. 数据返回: 当data可以使用的时候,调用这个方法。我们可以在这里获取data.
  5. 数据缓存: 允许我们在这里调用completionHandler缓存data,或者传入nil来禁止缓存

8.6 NSURLSession​Download​Delegate : task-level的面向download的代理方法

  1. 下载完成: 当一个下载task任务完成以后,这个方法会被调用。我们可以在这里移动或者复制download的数据
  2. 下载进度: 获取下载进度
  3. 重启下载: 重启一个下载任务(比如下载一半后停止然后过一点时间继续)。如果下载出错,NSError的keyNSURLSessionDownloadTaskResumeData里面包含重新开始下载的数据

8.7 NSURLSessionStreamDelegate : task-level的面向stream的代理方法

非HTTP或HTTPS连接代理方法.

8.8 NSURLSessionTaskTransactionMetrics(iOS10)

对发送请求/DNS查询/TLS握手/请求响应等各种环节时间上的统计. 更易于我们检测, 分析我们App的请求缓慢到底是发生在哪个环节, 并对此进行优化提升我们APP的性能.

8.9 NSURLSessionTaskMetrics(iOS10)

对发送请求/DNS查询/TLS握手/请求响应等各种环节时间上的统计. 更易于我们检测, 分析我们App的请求缓慢到底是发生在哪个环节, 并对此进行优化提升我们APP的性能.

  1. taskInterval : task从开始到结束总共用的时间
  2. redirectCount : task重定向的次数
  3. transactionMetrics : 一个task从发出请求到收到数据过程中派生出的每个子请求, 它是一个装着许多NSURLSessionTaskTransactionMetrics对象的数组. 每个对象都代表下图的一个子过程

9. AFURLSessionManager: NSObject

  • 主要流程:
  1. 初始化和管理NSURLSession,通过它来建立和管理各种Task。
  2. 初始化和管理NSRULSessionTask,通过不同task来发送不同请求。
  3. 管理各种认证功能、安全功能、请求重定向、数据处理。
  4. 管理和组织每个task的各种状态管理和通知管理。不同task的回调处理。
  5. 帮我们管理和处理了NSRULSession系列api的各种代理方法。简化了我们的处理。
  • 主要工能
  1. 初始化设置相关的api: 主要用于初始化(config/session/queue)、安全策略、网络状态监听等
  2. 获取Task的api: 任务的创建、任务的分类、任务完成队列处理、特殊情况的任务重新创建等
  3. 管理Task创建Block: 提供了很多处理Task的Block。不用去管理session系列繁琐的delegate方法了.
  4. 设置各种情况的代理回调:处理网络请求过程或者结束以后的数据处理、认证、通知、缓存等。我们可以通过设置这些Block来获取或者检测各种状态;涉及到的NSURLSession五个代理的综合回调, 内部通过AFURLSessionManagerTaskDelegate实现NSURLSession五个代理
  5. 很多notification的声明: 获取Task是否开始、是否完成、是否挂起、是否无效等各种通知

9.1 AFURLSessionManagerTaskDelegate:

  1. 接管NSURLSession各种delegate的实现.
  2. 绑定task与taskDelegate: 绑定task / 存储task下载的数据 / 下载或上传进度 / 进度与task同步(KVO)
  3. progress和task状态的同步(KVO实现);

9.2 _AFURLSessionTaskSwizzling:

主要实现了iOS7和iOS8系统上NSURLSession差别的处理。让不同系统版本NSURLSession版本基本一致

10. AFHttpSessionManager: AFURLSessionManager

  1. HTTP/1.1协议规定的HTTP请求方法有OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 这几种.
  2. 对各种请求方式的封装.
  3. 最终都调用dataTaskWithHTTPMethod:…这个方法;

11. Serialization:

11.1 AFURLRequestSerialization:

https://www.jianshu.com/p/96f115bcd913
主要实现了对于不同情况的请求的request对象的封装
尤其是对于multipart/form-data类型的request的封装,简化了我们自己封装过程的痛苦
请求头的编码解码、序列化、优化处理、简化请求拼接过程等

  • URLString和Parameters参数处理
  1. AFPercentEscapedStringFromString: 对urlString进行百分编码;
  2. AFQueryStringFromParameters: 调用3和5将字典转为URL的query参数;
  3. AFQueryStringPairsFromDictionary: 调用4实现字典转为URL的query参数;
  4. AFQueryStringPairsFromKeyAndValue: 把键值对转为URL的query参数;
  5. AFQueryStringPair: 把普通键值对变成百分编码的键值对并用=连接起来;
  • 提供序列化方法
    requestBySerializingRequest: withParameters: error:

  • AFStreamingMultipartFormData: 文件上传

  1. 用于拼接multipart/form-data的分隔符和文件的MIMEType.
  2. 负责multipart/form-data的Body的具体构建.
  3. 构造form-data数据.
  4. 遵循 AFMultipartFormData 协议,能管理 boundary 字符串、用于向 request 传输数据的 AFMultipartBodyStream对象.
  • AFMultipartBodyStream: 封装了4
  1. 有一个 HTTPBodyParts 属性,是一个 AFHTTPBodyPart 类型的数组.
  • AFHTTPBodyPart: form-data 的每一个 part
  1. 这个 part 的头部 header
  2. 分割字符串 boundary
  3. 内容区长度
  4. id 类型的 body
  5. 数据流 inputStream
  • AFMultipartFormData: 是一个文件上传的协议(file/data/stream/自定义);
  1. appendPartWithFileURL: name: error:
  2. appendPartWithFileURL: name: fileName: mimeType: error:
  3. appendPartWithInputStream: name: fileName: length: mimeType:
  4. appendPartWithFileData: name: fileName: mimeType:
  5. appendPartWithFormData: name:
  6. appendPartWithHeaders: body:
  • AFHTTPRequestSerializer
  1. init过程中遍历AFHTTPRequestSerializerObservedKeyPaths增加KVO观察.
  2. 根据不同平台配置不同的User-Agent内容;
  3. 各种setter方法: 重写蜂窝数据、缓存策略、cookie、管道、网络状态、超时的观察.用于测试这些属性变化是否崩溃等
  4. automaticallyNotifiesObserversForKey方法来阻止一些属性的KVO机制的触发.
  5. 各种请求头域处理: 获取或设置请求头域的key/value; 设置用户名和密码;
  6. 各种创建NSMutableURLRequest的方法:
  • AFHTTPRequestSerializerObservedKeyPaths:
  1. 指定了request请求序列化要观察的属性列表、是一个数组.
  2. 对蜂窝数据、缓存策略、cookie、管道、网络状态、超时这几个元素
  • AFJSONRequestSerializer
  1. 需要把Content-Type指定为"application/json.
  2. 同时HTTPBody需要使用JSON序列化:
  • AFPropertyListRequestSerializer
  1. 需要把Content-Type指定为"application/x-plist".
  2. 同时HTTPBody需要使用JSON序列化:

11.2 AFURLResponseSerialization: 是一个协议

网络返回数据的序列化、编码解码、序列化、数据处理等

  1. 协议方法-> responseObjectForResponse: data: error:
  2. 本地格式化错误信息: AFErrorWithUnderlyingError.
  3. AFErrorOrUnderlyingErrorHasCodeInDomain.
  4. 移除JSON中的null值AFJSONObjectByRemovingKeysWithNullValues
  • AFHTTPResponseSerializer
  1. init方法中acceptableStatusCodes: 有效接收的状态码200-299; acceptableContentTypes: 接收类型没有限制;
  2. validateResponse: data: error: 验证相应和数据的有效性; 无效是重新构建error信息;
  3. 默认返回的是二进制格式.
  • AFJSONResponseSerializer
  1. init方法中设置acceptableContentTypes: @“application/json”, @“text/json”, @"text/javascript”;
  2. responseObjectForResponse: data: error: 检验数据有效性, 并将data转为json.
  • AFXMLParserResponseSerializer
  • AFXMLDocumentResponseSerializer (macOS)
  • AFPropertyListResponseSerializer
  • AFImageResponseSerializer
  1. 图片格式: 很多种包括gif.
  2. 图片进行压缩处理: AFInflatedImageFromResponseWithDataAtScale
  • AFCompoundResponseSerializer
  1. 组合模式的序列.

12. Additional Functionality:

12.1 AFSecurityPolicy: 请求的认证功能

  • AFSSLPinningMode
  1. AFSSLPinningModeNone: 不绑定证书, 跟浏览器一样在系统的信任机构列表里验证服务端返回的证书。若证书是信任机构签发的就会通过,若是自己服务器生成的证书,这里是不会通过的。
  2. AFSSLPinningModePublicKey: 用证书绑定方式验证,客户端要有服务端的证书拷贝,只是验证时只验证证书里的公钥,不验证证书的有效期等信息。
  3. AFSSLPinningModeCertificate: 表示用证书绑定方式验证证书,需要客户端保存有服务端的证书拷贝,这里验证分两步,第一步验证证书的域名/有效期等信息,第二步是对比服务端返回的证书跟客户端返回的是否一致。
  • 获取指定公钥和证书的验证
  1. AFPublicKeyForCertificate: 获取指定证书的公钥.
  2. AFServerTrustIsValid: 在指定的证书和认证策略下,验证SecTrustRef对象是否是受信任的、合法的。
  3. AFCertificateTrustChainForServerTrust: 根据serverTrust获取认证的证书链.
  4. AFPublicKeyTrustChainForServerTrust: 获取serverTrust对象的认证链的公钥数组
  • 验证过程
  1. 证书集合和安全策略设置.
  2. evaluateServerTrust: 桥接证书与认证策略的对象

12.2 AFNetworkReachabilityManager:

负责网络状态变化的检测

13. AFN调用流程分析:

重点店是task和delegate之间的绑定和解除逻辑

  1. AFHTTPSessionManager: 发起网络请求(例如GET);
  2. AFHTTPSessionManager内部调用dataTaskWithHTTPMethod:方法(内部处理requestSerializer);
  3. dataTaskWithHTTPMethod内部调用父类AFURLSessionManager的dataTaskWithRequest: uploadProgress: downloadProgress: completionHandler方法;
  4. AFURLSessionManager中的dataTaskWithRequest方法内部设置全局session和创建task;
  5. AFURLSessionManager中的dataTaskWithRequest方法内部给task设置delegate(AFURLSessionManagerTaskDelegate);
  6. taskDelegate代理的初始化: 绑定task / 存储task下载的数据 / 下载或上传进度 / 进度与task同步(KVO)
  7. task对应的AFURLSessionManagerTaskDelegate实现对进度处理、Block调用、Task完成返回数据的拼装的功能等;
  8. setDelegate: forTask: 加锁设置通过一个字典处理Task与之代理方法关联; 添加对Task开始、重启、挂起状态的通知的接收.
  9. [downloadTask resume]后执行开始, 走代理回调方法(内部其实是NSURLSession的各种代理的实现);
  10. task完成后走URLSession: task: didCompleteWithError: 回调对返回的数据进行封装;
  11. 同时移除对应的task; removeDelegateForTask: 加锁移除8中的字典和通知;

你可能感兴趣的:(AFNetwork)