platforms: iOS|tvOS|watchOS|macOS|visionOS

Alley

用于与 HTTP(S) Web 服务通信的精简 URLSessionDataTask 微封装器。

为什么

在大多数需要从互联网获取数据的情况下,你

  1. 无论如何都想要获取目标 URL 的数据
  2. 如果无法获取数据,向最终用户显示一些有用的错误信息,并且 显示/记录实际发生的错误,以便你可以进行故障排除和调试

第二点锦上添花。第一点则至关重要,因为获取数据才是你做这一切的根本原因。

因此,Alley 的主要功能是针对预定义条件的自动请求重试

集成

只需将 Alley 文件夹拖到你的项目中。

或者通过 Swift Package Manager 添加此仓库的 URL。

用法

你可能已经有一些 URLSession 实例可以使用。然后,与其这样

let urlRequest = URLRequest(...)

do {
	let data = try await urlSession.data(for: urlRequest)
} catch let err {
	//...process error
}

使用 Alley,你将这样做

let urlRequest = URLRequest(...)

do {
	let data = try await urlSession.alleyData(for: urlRequest)
} catch let err {
	//...process NetworkError
}

如果请求成功,你将获得从服务返回的 Data 实例,你可以将其转换为你期望的任何类型。

如果失败,你将获得 NetworkError 的实例。

NetworkError

这是一个自定义错误(由枚举实现),它 - 首先 - 封装了 URLSessionDataTask 返回的内容。因此,最初的几个可能选项是

///	`URLSession` errors are passed-through, handle as appropriate.
case urlError(URLError)

///	URLSession returned an `Error` object which is not `URLError`
case generalError(Swift.Error)

接下来,如果返回的 URLResponse 不是 HTTPURLResponse

case invalidResponseType(URLResponse)

现在,如果是 HTTPURLResponse,但状态代码为 400 或更高,这是你正在通信的 Web 服务端点返回的错误。因此,你将获得完整的 HTTPURLResponseData(如果存在),以便调用者可以弄清楚发生了什么。

case endpointError(HTTPURLResponse, Data?)

在调用对象中,你可以使用这些值,并尝试构建与给定特定 Web 服务相关的强类型自定义错误的实例。

如果状态代码在 2xx 范围内,你可能会遇到响应体丢失的情况。

case noResponseData(HTTPURLResponse)

这可能是一个错误,也可能不是。如果你执行 PUTDELETE 甚至 POST 请求,你的服务可能不会返回任何数据作为有效响应(只有 200 OK 或其他)。在这种情况下,通过像这样调用 perform 来防止此错误

let urlRequest = URLRequest(...)

let data = try await urlSession.alleyData(for: urlRequest, allowEmptyData: true)

你将在其中获得空的 Data()

还有一种可能的 NetworkError 值,它与... 相关

自动重试

默认重试次数为 10

此值自动用于所有网络调用,但你可以通过简单地为 maxRetries 参数提供适当的数字来按每次调用进行调整。

let urlRequest = URLRequest(...)

let data = try await urlSession.alleyData(for: urlRequest, maxRetries: 5)

自动重试如何工作?

如果引发 NetworkErrorAlley 将检查其 shouldRetry 属性,如果为 true,它将重试计数器递增 1 并再次执行 URLSessionDataTask。一遍又一遍...直到达到 maxRetries 值,然后它将返回 NetworkError.inaccessible 作为结果。

每次重试延迟半秒钟,但你可以在调用 alleyData 时提供任何你想要的值(包括 0),参数为 retryInterval

let urlRequest = URLRequest(...)

let data = try await urlSession.alleyData(for: urlRequest, retryInterval: 0.3)

你可以通过更改 shouldRetry 属性的实现来自定义行为(在这种情况下,我建议手动将 Alley 文件夹复制到你的项目中)。


就这些了。Alley 的设计宗旨是保持简洁,以鼓励尽可能少地编写代码,并隐藏掉经常重复的样板代码。

许可证

MIT 许可证, 就像我所有的开源代码一样。

回馈

如果你觉得这段代码有用,请考虑 请我喝一两杯咖啡。☕️😋