测试已测试 | ✓ |
Lang语言 | SwiftSwift |
许可证 | MIT |
发布最后发布 | 2017年2月 |
SwiftSwift 版本 | 3.0 |
SPM支持 SPM | ✓ |
由Roy Ratcliffe维护。
Faraday 是一个 Swift 的 HTTP 客户端。它有两个主要目标:灵活性和简洁性。
灵活,因为客户端和服务器的连接是复杂的事件。它们需要分解成可管理的部分。Faraday 通过采用服务器端软件开发架构通常采用的方法(以某种形式),来实现这一点:中间件堆栈。请求和响应通过一组中间件组件传递,这些组件为传输请求做好准备,随后为客户应用中使用的响应做好准备。在设置时,您配置连接的中间件组件,然后中间件将处理连接的请求设置和响应拆卸。应用程序只需检查处理后的结果,而无需亲手处理令人混乱的原料——用美食比喻。
简洁,因为框架只做它的工作,没有更多。它不施加
简而言之,它试图保持在不干扰的情况下,保持清新干净。
Faraday 旨在成为类似 Ruby 对应版本的 HTTP 客户端,统治所有,就像它的 Ruby 对应版本一样。Swift 的 Faraday 框架是一个模块化的 HTTP 客户端库,强烈灵感来自 Ruby Faraday,而 Faraday 又强烈灵感来自 Rack。该框架在处理 HTTP 请求-响应周期时采用了 Rack 中间件的概念。当您建立连接时,您会创建一个中间件元素堆栈来处理请求和响应。
以下描述了如何使用基本连接,但您可以添加自己的中间件来自定义连接。以 Faraday HAL 为例。它包括用于通过 HTTP 连接使用超文本应用语言 (HAL) 的额外中间件处理器。
let connection = Connection()
connection.url = URL(string: "http://faraday-tests.herokuapp.com/")
connection.use(handler: EncodeJSON.Handler())
connection.use(handler: DecodeJSON.Handler())
connection.use(handler: Logger.Handler())
connection.use(handler: URLSessionAdapter.Handler())
URL 的尾部斜杠非常重要。没有它,合并 URL 将替换整个路径,而不是仅追加路径。这是与 Apple 的 URL
类相关的“功能”。
上述代码使用 Apple 的 URLSession
适配器构建了一个基于日志的 JSON 连接。请求首先看到编码 JSON 处理器,该处理器使用 JSON 序列化将请求数据编码为 JSON 编码的字符串,从字典到 JSON 编码的字符串。然后 JSON 解码器看到请求但什么都不做;解码器只在响应到达时处理响应。接下来,日志处理器看到请求并将其详细信息记录到调试控制台,使用 NSLog
。最后,URL 会话适配器看到请求并执行它。
当响应到达时,响应体和头信息会通过中间件堆栈向上传递。日志记录器记录响应。解码器将响应体从 JSON 转换为字典。最后,编码器看到响应并什么也不做,因为它只关心请求。结果以异步方式通过 Response
对象到达。
使用中间件处理请求和响应模仿了服务器端软件处理请求和响应的典型方式。它有助于分解复杂的事情。堆栈的不同元素专注于他们各自的交互方面。“Rack 堆栈”是处理请求-响应周期的有用软件分解工具,适用于服务器端和客户端。
一旦您使用基本 URL 和中间件设置了连接,您就可以使用它来运行请求:GET、HEAD、DELETE、POST、PUT、PATCH 或任何其他方法。
例如,您可以使用以下方式使用连接运行 GET
请求:
_ = connection.get(path: "path/to/resource").onComplete { env in
guard let response = env.response else { return }
// Handle the unwrapped response. It contains the response status,
// response headers and response body.
}
这通过将 path/to/resource
添加到基本 URL 以运行异步 GET
请求。请注意,完成捕获是异步地在一个独立线程中运行的,这个线程是由 iOS 为相关的 URL 会话数据任务分配的。如果需要,可以将其跳转到另一个 dispatch 队列。
请求通常包括参数或查询值。通过向 run-request 方法提供请求处理器,设置请求所需的任何参数,如下所示。
let response = connection.post { request in
request.setQuery(values: ["world"], forName: "hello")
// Do other things to configure the request, e.g. adjust headers, add
// authentication.
}
// We have the response, but the response is not yet complete. It exists as a
// placeholder until completion. The request runs asynchronously, as does its
// corresponding response.
_ = response.onComplete { env in
guard let response = env.response else { return }
let body = response.body as? NSDictionary
}
在这种情况下,POST 请求没有提供附加路径。它只使用基本 URL,但它会在请求 URL 的末尾添加参数,即字面地 ?hello=world
将出现在请求 URL 的末尾。请求允许同一名称的多个值,因此可以设置查询 值。
您可以使用请求处理器来设置请求授权。Faraday 预设了两种常用的授权方法:基本授权和 token 授权。以下配置了一个特定的请求并进行基本授权,即登录名和密码。
let response = connection.get { request in
request.path = "path/to/resource"
request.body = ["ping": "pong"]
_ = request.headers.auth(login: "login", pass: "pass")
// The headers for this request will now include the following basic authorisation.
// Authorization: Basic bG9naW46cGFzcw==
}
您可以将连接本身设置授权,这样所有请求都会携带授权头。使用 connection.headers
访问连接头信息;这些将成为所有请求的默认头。单个请求头将与默认值合并并覆盖默认值。
令牌授权工作方式类似,只是参数不同,即
_ = request.headers.auth(token: "abcdef", options: ["foo": "bar"])
请求头将包括
Authorization: Token token=abcdef,foo=bar
这对连接以及单个请求都适用。
URL 会话适配器处理分块响应。这是服务器为同一请求发送多个响应的地方。在底层,HTTP 请求-响应周期只是一个临时的 TCP 流连接。然而,对于分块响应,服务器保持连接打开并传递多个响应。对于每个响应块,服务器发送块长度和块本身。
对于分块传输,您只需像平常一样设置并使用Faraday连接即可,只是响应在每个块上完成多次。请参阅心跳测试以获取分块传输的详细示例。
Swift Faraday与Ruby Faraday之间有一些重要的区别。例如,Swift仅处理异步响应。请求以同步方式成为未完成的响应,但请求在另一个线程中异步经过适配器。之后,当请求成功或失败时,响应完成。完成的响应以反向中间件堆栈顺序调用它们的完整的处理程序。
构造是另一个区别。Swift并不方便地允许从类动态实例化实例。您不能提供一个字符串并获得一个实例。Swift 2有绕过这一点的办法,但都不是涉及Objective-C的。相反,中间件组件按照约定定义一个嵌套类:一个Rack处理程序。这个类及其子类的实例知道如何根据Rack应用构建一个中间件实例。