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 依赖包,如下图所示

Swift Server 之 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 渲染。