Swift版本AFNetworking。 最近我在对公司的项目Alamofire版本进行升级,从4.x升到5.x,pod升级完后,代码报了不少错。af5有很多的改动。

完整结构图

https://alamofire.github.io/Alamofire/

官方的5.0迁移指南

https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%205.0%20Migration%20Guide.md
Alamofire的核心架构已经重写,以遵循各种最佳实践。
DispatchQueue的使用情况已经更新,以遵循Apple推荐的最佳实践。这意味着Alamofire在同时处理多个请求时可以更好地扩展,不会像以前的版本那样导致队列耗尽。这将提高整体性能,降低Alamofire对应用程序和系统的影响。
内部api中已经明确了职责范围,从而更容易实现某些特性,比如新的EventMonitor协议和按请求SSL失败错误等。
代码编写时受益于各种线程净化程序,尤其是线程净化器(thread sanitizer),因此与以前的版本相比,线程和其他运行时问题要少得多。

下面是官方的使用指导,在网上搜索af的问题,很多还是基于4来的。有使用上的问题建议直接查看官方文档
https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md

Request完全负责http请求的发起和接收

Session 负责创建Request实例

Result+Alamofire.swift

在AF4.x版本依赖了Result库,不过swift5中系统库已经引入了Result类型,因此AF5.x采用了Result系统库版本,Result是一个枚举,有两个case,分别是.success和.failure,非常适合http请求这种返回结果有成功失败两种情况的。Success和Failure是泛型,Success支持任何类型,Failure必须遵从Error协议。

  1. public enum Result<Success, Failure> where Failure : Error {
  2. /// A success, storing a `Success` value.
  3. case success(Success)
  4. /// A failure, storing a `Failure` value.
  5. case failure(Failure)
  6. ...

Result+Alamofire.swift中对Result 进行了扩展,增加了2个只读计算属性success和failure,方便请求回调直接取值。

SessionDelegate.swift

这个类干嘛的,它处理所有的URLSession delegate回调方法,非常重要,由Session持有。SessionDelegate内部有一个stateProvider的weak变量持有Session。
这个类改动非常大,AF4.x版本这个类提供了许多闭包属性方便外界操作,比如我用到的http证书信任,升级到5之后发现全都改了。原来的sessionDidReceiveChallengeWithCompletion已经没有了,需要用到serverTrustManager这么个玩意。serverTrustManager是Session的成员变量,我们初始化Session实例的时候可以配置serverTrustManager。

关于安全这一块,关注两个ServerTrustEvaluatingServerTrustManager

ServerTrustEvaluating.swift

  • ServerTrustEvaluating 协议,评估服务器信任。所有的评估信任类都要conform这个协议
  • ServerTrustManager 我们app中可能存在多个请求host,每个host的证书认证方式都可能不一样。这里存放单个host的认证策略,是一个管理器。

    ServerTrustManager

    ```javascript let evaluators: [String: ServerTrustEvaluating] = [ // By default, certificates included in the app bundle are pinned automatically. “cert.example.com”: PinnedCertificatesTrustEvalutor(), // By default, public keys from certificates included in the app bundle are used automatically. “keys.example.com”: PublicKeysTrustEvalutor(), ]

let manager = ServerTrustManager(evaluators: serverTrustPolicies)

  1. <a name="m0p7W"></a>
  2. #### 评估信任方式
  3. - DefaultTrustEvaluator:默认的评估方式,使用SecPolicyCreateSSL(_:_:)策略进行评估,验证服务器证书和域名(域名验证可关闭)
  4. - RevocationTrustEvaluator:在 DefaultTrustEvaluator 基础上,增加用检查证书撤销的策略进行评估
  5. - PinnedCertificatesTrustEvaluator:在 DefaultTrustEvaluator 基础上,增加 Certificate Pinning 检查
  6. - PublicKeysTrustEvaluator:在 DefaultTrustEvaluator 基础上,增加 Public Key Pinning 检查
  7. - CompositeTrustEvaluator:组合评估,使用多种处理方式进行评估
  8. - DisabledEvaluator:不验证,直接通过,生产环境不要用
  9. <a name="aFopP"></a>
  10. ### AlamofireExtended.swift
  11. 包含一个名为AlamofireExtension的结构体,AlamofireExtended的协议<br />先看下面这段代码,在协议的默认实现中,2个af分别返回类型和实例,可以学习下写法
  12. ```swift
  13. public extension AlamofireExtended {
  14. /// Static Alamofire extension point.
  15. static var af: AlamofireExtension<Self>.Type {
  16. get { return AlamofireExtension<Self>.self }
  17. set {}
  18. }
  19. /// Instance Alamofire extension point.
  20. var af: AlamofireExtension<Self> {
  21. get { return AlamofireExtension(self) }
  22. set {}
  23. }
  24. }

以往要扩展一个类的时候,通常做法就是使用extension,但是在这会让其他模块都可以访问到。假设开发一个第三方库,我们不想让自己的某些扩展那么容易被用户敲代码时候提示出来,或者说不知道自己定义的某个扩展方法是否和其他地方的重名冲突,同时希望拒绝前缀的写法,那么这个文件里就教会我们一个很好的写法。一个conform AlamofireExtended协议的实体,本类通过一个结构体坐中间层,在结构体中增加要扩展的方法和变量。起到了类似命令空间般的效果。我认为非常值得学习。