
这里每天分享一个 iOS 的新知识,快来关注我吧
Swift HTTP Types 介绍
Swift 最近发布了一个新开源包:Swift HTTP Types。这个库的目标旨在为 Swift 中的客户端/服务器 HTTP 操作提供一组共享的通用类型,包括 HTTPRequest、HTTPResponse 和 HTTPFields。
使用 swift 写的应用中使用网络的场景无处不在,涵盖客户端、服务器、中间件以及互联网和其他网络上的许多其他参与者。HTTP 是最流行的网络技术之一,为世界各地的日常体验提供动力。
在以前,系统 HTTP 的实现需要使用 Foundation 框架中的 URLSession API。对于用 Swift 实现的服务器项目,则推荐的使用 SwiftNIO。
为了提供在 Swift 中使用 HTTP 的最佳体验,跨许多项目有用的共享通用类型,Swift HTTP Types 应运而生,其目标是替换 SwiftNIO 的 HTTPRequestHead 和 HTTPResponseHead,以及 Foundation 的 URLRequest 和 URLResponse。
我大致看了下源码,HTTPRequest 和 HTTPResponse 代表客户端和服务器的 HTTP 消息类型。通过在多个项目中使用它们,可以在客户端和服务器之间共享更多代码,从而消除使用多个框架时在类型之间进行转换的成本。
HTTPTypesFoundation 文件夹中主要提供为 Foundation 中使用新的 HTTP 类型提供了能力,包括新类型和 Foundation URL 类型之间的双向转换器,以及使用新类型的 URLSession 便利方法。
Swift HTTP Types 的使用方法
要使用这个库,需要使用 SPM 引入,将以下依赖项添加到您的 Package.swift 中:
dependencies: [
.package(url: "https://github.com/apple/swift-http-types.git", from: "0.1.0")
]
创建一个请求:
let request = HTTPRequest(method: .get,
scheme: "https",
authority: "www.apple.com",
path: "/")
也可以使用 URL 来创建:
var request = HTTPRequest(method: .get,
url: URL(string: "https://www.apple.com/")!)
request.method = .post
request.path = "/upload"
创建完请求之后也可以对请求对象做出修改:
request.method = .post
request.path = "/upload"
修改请求头:
request.headerFields[.userAgent] = "MyApp/1.0"
request.headerFields[raw: .acceptLanguage] = ["en-US", "zh-Hans-CN"]
如果你在用 Swift 做服务端应用,创建一个响应可以这样写:
let response = HTTPResponse(status: .ok)
也可以使用相同的方法访问请求头里的信息:
request.headerFields[.userAgent] // "MyApp/1.0"
request.headerFields[.acceptLanguage] // "en-US, zh-Hans-CN"
与 Foundation 库一起使用
使用 Foundation 中的 URLSession,我们可以轻松创建一个新的 HTTPRequest 来向“www.apple.com”发送 POST 请求。在此请求上设置自定义 User-Agent 标头字段值非常直观:
var request = HTTPRequest(method: .post, url: URL(string: "https://www.apple.com/upload")!)
request.headerFields[.userAgent] = "MyApp/1.0"
let (responseBody, response) = try await URLSession.shared.upload(for: request, from: requestBody)
guard response.status == .created else {
// 处理错误
}
与 SwiftNIO 一起使用
当 swift-nio-extras 软件包变得稳定时,SwiftNIO 集成将在该软件包中提供。要配置 NIO 通道处理程序以与新的 HTTP 类型一起使用,我们可以在其他通道处理程序之前添加 HTTP2FramePayloadToHTTPServerCodec:
NIOTSListenerBootstrap(group: NIOTSEventLoopGroup())
.childChannelInitializer { channel in
channel.configureHTTP2Pipeline(mode: .server) { channel in
channel.pipeline.addHandlers([
HTTP2FramePayloadToHTTPServerCodec(),
ExampleChannelHandler()
])
}.map { _ in () }
}
.tlsOptions(tlsOptions)
然后同时处理 HTTPRequest 和 HTTPResponse:
final class ExampleChannelHandler: ChannelDuplexHandler {
typealias InboundIn = HTTPTypeServerRequestPart
typealias OutboundOut = HTTPTypeServerResponsePart
func channelRead(context: ChannelHandlerContext, data: NIOAny) {
switch unwrapInboundIn(data) {
case .head(let request):
// 处理请求头
case .body(let body):
// 处理请求体
case .end(let trailers):
// 完成请求回调
let response = HTTPResponse(status: .ok)
context.write(wrapOutboundOut(.head(response)), promise: nil)
context.writeAndFlush(wrapOutboundOut(.end(nil)), promise: nil)
}
}
}
最终使用下来可以发现,有了这个库处理请求类型真的会方便很多。
参考资料
[1]
Swift HTTP Types: github.com/apple/swift…
本文同步自微信公众号 “iOS新知”,每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!