拦截器是一个包,旨在解决在网络 API 及其响应中需要进行某些配置时遇到的问题。 我们需要基于单一职责原则,以集中的形式拦截一些信息或添加全局配置。 这个包背后的想法很简单,但实现需要一些准备,请看下面的图片。
在这种情况下,拦截器在创建 URLRequest
后应用,并在 URLSession
回调后应用。
首先,在你的代码中应用设置后,我们需要基于两个协议 ResquestInterceptor
和 ResponseInterceptor
创建拦截器对象。
struct TokenInterceptor: RequestInterceptor {
func intercept(_ request: inout URLRequest) throws {
request.addValue("Bearer HASH-test-1234", forHTTPHeaderField: "Authorization")
}
}
class BlockInterceptorSpy: ResponseInterceptor {
func intercept(_ data: Data?, response: URLResponse?, error: Error?) {
if let value = response as? HTTPURLResponse, value.statusCode == 401 {
...
}
}
}
之后,我们可以将这些对象添加到链表中 (在此查看实现) 基于 Responder 包,我们将通过函数 Interceptor.add(_ :)
添加每个对象。
var interceptor = Interceptor()
interceptor.add(TokenInterceptor()).add(BlockInterceptorSpy())
这非常简单,看看下面的代码
这里,我们在创建 URLRequest
后应用请求拦截器。函数 applyRequest
将遍历添加的每个对象,并与 ResquestInterceptor
相关联,并将更改或应用一些数据。
let url = URL(string: "http://test.com")
var request = URLRequest(url: url)
try interceptor.applyRequest(&request)
下一步,在你的代码中的 URLSession 回调后添加拦截器。 这一点非常简单,只需将函数 applyResponse
放在属性 completionhandler
上,它们的类型是相等的。
let task = session.dataTask(with: url, completionHandler: interceptor.applyResponse { data, response, error in
...
})
task.resume()
就这样!
要将 Interceptor
用作 Swift Package Manager 包,只需在你的 Package.swift 文件中添加以下内容。
.package(url: "https://github.com/bfernandesbfs/Interceptor.git", .upToNextMajor(from: "0.0.1"))
Interceptor 依赖于 Responder 包