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协议。
public enum Result<Success, Failure> where Failure : Error {
/// A success, storing a `Success` value.
case success(Success)
/// A failure, storing a `Failure` value.
case failure(Failure)
...
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。
关于安全这一块,关注两个ServerTrustEvaluating和ServerTrustManager
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)
<a name="m0p7W"></a>
#### 评估信任方式
- DefaultTrustEvaluator:默认的评估方式,使用SecPolicyCreateSSL(_:_:)策略进行评估,验证服务器证书和域名(域名验证可关闭)
- RevocationTrustEvaluator:在 DefaultTrustEvaluator 基础上,增加用检查证书撤销的策略进行评估
- PinnedCertificatesTrustEvaluator:在 DefaultTrustEvaluator 基础上,增加 Certificate Pinning 检查
- PublicKeysTrustEvaluator:在 DefaultTrustEvaluator 基础上,增加 Public Key Pinning 检查
- CompositeTrustEvaluator:组合评估,使用多种处理方式进行评估
- DisabledEvaluator:不验证,直接通过,生产环境不要用
<a name="aFopP"></a>
### AlamofireExtended.swift
包含一个名为AlamofireExtension的结构体,AlamofireExtended的协议<br />先看下面这段代码,在协议的默认实现中,2个af分别返回类型和实例,可以学习下写法
```swift
public extension AlamofireExtended {
/// Static Alamofire extension point.
static var af: AlamofireExtension<Self>.Type {
get { return AlamofireExtension<Self>.self }
set {}
}
/// Instance Alamofire extension point.
var af: AlamofireExtension<Self> {
get { return AlamofireExtension(self) }
set {}
}
}
以往要扩展一个类的时候,通常做法就是使用extension,但是在这会让其他模块都可以访问到。假设开发一个第三方库,我们不想让自己的某些扩展那么容易被用户敲代码时候提示出来,或者说不知道自己定义的某个扩展方法是否和其他地方的重名冲突,同时希望拒绝前缀的写法,那么这个文件里就教会我们一个很好的写法。一个conform AlamofireExtended协议的实体,本类通过一个结构体坐中间层,在结构体中增加要扩展的方法和变量。起到了类似命令空间般的效果。我认为非常值得学习。