Swift Server Workgroup (SSWG) 成立后一直致力于提供更好用更标准的 Swift 网络相关依赖库,推动 Swift 在服务端的工作,今天本博客的主角 async-http-client 就是 SSWG 孵化项目之一,async-http-client 是基于 swift-nio 构建的异步 http 客户端。
异步 http 客户端我们都知道,说白了就是一个 http 请求的客户端依赖库,我们写的应用中大部分服务器中的数据就是通过 http 请求依赖库来请求获取的。
那么 swift-nio 又是一个啥东西呢?官方介绍是说 swift-nio 是一个跨平台异步事件驱动的网络应用程序框架,基于 swift-nio 实现高性能的服务器和客户端。通俗一点讲就是 swift-nio 是一个通用的网络框架,这就不仅仅只是 http 的网络请求了,我们可以利用 swift-nio 实现 tcp 、udp 等网络通讯,也能利用 swift-nio 封装出 http、ftp 等应用层网络框架。async-http-client 就是 Swift Server Workgroup 孵化的 http 网络请求框架实现。
swift-nio 代码仓库: https://github.com/apple/swift-nio
async-http-client 代码仓库: https://github.com/swift-server/async-http-client
在 IOS 项目中添加 async-http-client 依赖库
首先在 Package Dependencies 中添加 async-http-client 依赖包,如下图所示
如果使用的是 Package.swift 的话添加
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.9.0")
使用 async-http-client 发起请求
import AsyncHTTPClient
Task {
do {
let client = HTTPClient(eventLoopGroupProvider: .singleton)
let request = HTTPClientRequest(url: "https://xkcd.com/info.0.json")
let response = try await client.execute(request, timeout: .seconds(30))
if response.status == .ok {
var body = try await response.body.collect(upTo: 1024 * 1024) // 1 MB
if let bytes = body.readBytes(length: body.readableBytes) {
print("body: \(String(bytes: bytes, encoding: .utf8))")
}
} else {
// handle remote error
print("error: \(response.status)")
}
try await client.shutdown()
} catch {
print("error: \(error)")
}
}
首先调用 HTTPClient init 方法构建 HTTPClient 对象,HTTPClient init 方法还支持传一个 configuration 参数该参数的类型是 Configuration 结构体,在 Configuration 结构体中有如下参数配置
tlsConfiguration: TLSConfiguration? = nil, // tls 配置
redirectConfiguration: RedirectConfiguration? = nil, // 重定向配置
timeout: Timeout = Timeout(), // 超时时间
connectionPool: ConnectionPool = ConnectionPool(), // 连接池配置
proxy: Proxy? = nil, // 代理配置
ignoreUncleanSSLShutdown: Bool = false, // 是否忽略不安全的 ssl
decompression: Decompression = .disabled // 自动解压,支持的算法有 gzip 和 deflate
通过 HTTPClientRequest 构建 Http 请求对象,通过 HTTPClientRequest 对象可以配置请求 URL,请求方法,请求头,请求体等参数。
var request = HTTPClientRequest(url: "https://xkcd.com/info.0.json")
request.method = .POST // 配置请求方法为 POST
request.headers = HTTPHeaders(["token" : "xxxxxxxx"]) // 添加请求头 token
request.body = .bytes(.init(string: "hello")) // 添加请求体内容 hello
调用 HTTPClient 对象的 execute 方法即可发起请求并且得到响应对象 HTTPClientResponse,通过 HTTPClientResponse 就能拿到响应状态、响应头、响应体数据。
最后记得调用 HTTPClient 的 shutdown 函数关闭请求,当然记得不要在主进程调用不然会导致阻塞 UI 渲染。