特性
- 可链接的请求/响应函数
- URL / JSON 参数编码
- 上传文件 / Data / 流 / 多表单数据
- 使用请求或者恢复数据下载文件
- 使用 URLCredential 进行身份验证
- HTTP 响应验证
- 带有进度的上传和下载闭包
- cURL 命令的输出
- 动态调整和重试请求
- TLS 证书和公钥固定
- 网络可达性
- 全面的单元和集成测试覆盖率
AF ,它是对 Session.default 的引用。
发起请求
1 | AF.request("https://httpbin.org/get").response { response in |
这实际上是 Alamofire Session 类型上用于发出请求的两个顶层 APIs 的一种形式。它的完整定义如下:
1 | open func request<Parameters: Encodable>( |
此方法创建一个 DataRequest,同时允许组合来自各个组件(如 method 和 headers )的请求,同时还允许每个传入 RequestInterceptors 和 Encodable 参数。
这个 API 的第二个版本要简单得多:
1 | open func request( |
此方法为遵循 Alamofire 的 URLRequestConvertible 协议的任何类型创建 DataRequest 。所有不同于前一版本的参数都封装在该值中,这会产生非常强大的抽象。
请求参数和参数编码器
Alamofire 支持将任何 Encodable
类型作为请求的参数。然后,这些参数通过遵循 ParameterEncoder
协议的类型传递,并添加到 URLRequest 中,然后通过网络发送。Alamofire 包含两种遵循 ParameterEncoder 的类型:JSONParameterEncoder
和 URLEncodedFormParameterEncoder
。这些类型涵盖了现代服务使用的最常见的编码。
1 | struct Login: Encodable { |
URLEncodedFormParameterEncoder
URLEncodedFormParameterEncoder
将值编码为 URL 编码字符串,以将其设置为或附加到任何现有 URL 查询字符串,或设置为请求的 HTTP body。通过设置编码的目的地,可以控制编码字符串的设置位置。URLEncodedFormParameterEncoder.Destination
枚举有三种情况:
.methodDependent
- 对于 .get
、.head
、.delete
请求,它会将已编码查询字符串应用到现有的查询字符串中;对于其他类型的请求,会将其设置为HTTP body
。- .
queryString
- 将编码字符串设置或追加到请求的 URL 中。 - .
httpBody
- 将编码字符串设置为URLRequest
的 HTTP body。
如果尚未设置 Content-Type
,那么会把具有 HTTP body 的已编码请求的 HTTP header 设置为 application/x-www-form-urlencoded; charset=utf-8
在内部,URLEncodedFormParameterEncoder
使用 URLEncodedFormEncoder
把 Encodable
类型编码为 URL 编码形式的 String
。此编码器可用于自定义各种类型的编码,包括使用 ArrayEncoding
的 Array
、使用 BoolEncoding
的Bool
、使用 DataEncoding
的 Data
、使用 DateEncoding
的 Date
、使用 KeyEncoding
的 keys
以及使用 SpaceEncoding
的空格。
使用 URL 编码参数的 GET 请求
1 | let parameters = ["foo": "bar"] |
使用 URL 编码参数的 POST 请求
1 | let parameters: [String: [String]] = [ |
JSONParameterEncoder
JSONParameterEncoder
使用 Swift 的 JSONEncoder
对 Encodable
值进行编码,并将结果设置为 URLRequest
的 httpBody
。如果 Content-Type
尚未设置,则将其设置为 application/json
JSON 编码参数的 POST 请求
1 | let parameters: [String: [String]] = [ |
手动对URLRequest进行参数编码
ParameterEncoder
APIs 也可以在 Alamofire 之外使用,方法是直接在URLRequest 中编码参数
1 | let url = URL(string: "https://httpbin.org/get")! |
HTTP Headers
Alamofire 包含自己的 HTTPHeaders
类型,这是一种顺序保持且不区分大小写
的 HTTP header name/value 对的表示。HTTPHeader 类型封装单个 name/value 对,并为常用的 headers 提供各种静态值。
向 Request 添加自定义 HTTPHeaders 就像向 request 方法传递值一样简单:
1 | let headers: HTTPHeaders = [ |
HTTPHeaders 也可以由 HTTPHeader 数组构造:
1 | let headers: HTTPHeaders = [ |
对于不会变的 HTTP headers,建议在 URLSessionConfiguration 上设置它们,以便让它们自动应用于底层 URLSession 创建的任何 URLSessionTask。
默认的 Alamofire Session
为每个 Request 提供一组默认的 headers。其中包括:
- Accept-Encoding,默认为 br;q=1.0, gzip;q=0.8, deflate;q=0.6,根据 RFC 7230 §4.2.3。
- Accept-Language,默认为系统中最多 6 种首选语言,格式为 en;q=1.0,根据 RFC 7231 §5.3.5。
- User-Agent,其中包含有关当前应用程序的版本信息。例如:iOS Example/1.0 (com.alamofire.iOS-Example; build:1; iOS 13.0.0) Alamofire/5.0.0,根据 RFC 7231 §5.5.3。
如果需要自定义这些 headers,则应创建自定义 URLSessionConfiguration
,更新 defaultHTTPHeaders
属性,并将配置应用于新 Session 实例。使用URLSessionConfiguration.af.default
来自定义配置,会保留 Alamofire 的默认 headers。
响应验证
如果响应具有不可接受的状态代码或 MIME 类型,则在响应处理程序之前调用 validate()
将导致生成错误
自动验证
validate()
API 自动验证状态代码是否在 200..<300
范围内,以及响应的 Content-Type
header 是否与请求的 Accept
匹配(如果有提供)。
1 | AF.request("https://httpbin.org/get").validate().responseJSON { response in |
手动验证
1 | AF.request("https://httpbin.org/get") |
响应处理
Alamofire 的 DataRequest
和 DownloadRequest
都有相应的响应类型:DataResponse<Success, Failure: Error>
和 DownloadResponse<Success, Failure: Error>
。这两个类型都由两个泛型组成:序列化类型和错误类型。默认情况下,所有响应值都将生成 AFError 错误类型(DataResponse<Success, AFError>
)。Alamofire 在其公共 API 中使用了更简单的 AFDataResponse<Success>
和 AFDownloadResponse<Success>
,它们总是有 AFError 错误类型。UploadRequest 是 DataRequest 的一个子类,使用相同的 DataResponse 类型。
处理在 Alamofire 中发出的 DataRequest 或 UploadRequest 的 DataResponse 涉及到链接 response handler,例如 responseJSON 链接到 DataRequest:
1 | AF.request("https://httpbin.org/get").responseJSON { response in |
在上面的示例中,responseJSON
handler 被添加到 DataRequest
中,以便在 DataRequest
完成后执行。传递给 handler 闭包的参数是从响应属性来的 JSONResponseSerializer
生成的 AFDataResponse<Any>
值。
此闭包并不阻塞执行以等待服务器的响应,而是作为回调添加,以便在收到响应后处理该响应。请求的结果仅在响应闭包的范围内可用。任何依赖于从服务器接收到的响应或数据的执行都必须在响应闭包中完成。
默认情况下,Alamofire 包含六个不同的数据响应 handlers,包括:
1 |
|
没有一个响应 handlers 对从服务器返回的 HTTPURLResponse 执行任何验证。
例如,400..<500 和 500..<600 范围内的响应状态代码不会自动触发错误。Alamofire 使用响应验证链接来实现这一点。