基于 URLSession 的轻量级封装,方便进行网络请求,并提供基于 Decodable 协议或自定义解码策略的强类型响应。
基于 Decodable 协议的强类型响应
let result = await manager.decodable.request(TestInfo.self, address: address)
manager.decodable.request(TestInfo.self, address: address) { result in ... }.start()
预定义的 API,支持基本类型:Void, Data, any Decodable, Image, Any(JSON)
async/await 和闭包两种策略在同一接口中提供
使用 Deserializable
定义您自己的解码策略或类型
使用 keyPath
解码响应中嵌套的 JSON 对象。
插件 (Plugin) 类似于 Android 拦截器。在运行时处理每一个请求-响应!通过验证、日志记录、身份验证等功能来实现您自己的魔法。
使用 PluginPriority (插件优先级) 定义插件链式执行的顺序。
使用 StopTheLine (停止链) 机制来处理需要停止整个网络并等待您执行操作的情况:更新身份验证 Token、处理验证码等。
使用 HTTPStubServer 在运行时模拟您自己的网络。在您的服务器尚未准备就绪时也能进行开发!
使用 SmartTask 管理网络请求的生命周期。取消销毁请求或手动处理分离的任务 - 一切尽在掌握!
可以轻松地与 SmartImage 结合使用,用于图像加载。
pdf
格式)。pdf
格式)。public protocol RequestManager {
/// ``Void`` request manager.
var void: TypedRequestManager<Void> { get }
/// ``Decodable`` request manager.
var decodable: DecodableRequestManager { get }
// MARK: - strong
/// ``Data`` request manager.
var data: TypedRequestManager<Data> { get }
/// ``Image`` request manager.
var image: TypedRequestManager<Image> { get }
/// ``JSON`` request manager.
var json: TypedRequestManager<Any> { get }
// MARK: - optional
/// ``Data`` request manager.
var dataOptional: TypedRequestManager<Data?> { get }
/// ``Image`` request manager.
var imageOptional: TypedRequestManager<Image?> { get }
/// ``JSON`` request manager.
var jsonOptional: TypedRequestManager<Any?> { get }
// MARK: - custom
/// Custom request manager which can be used to create a request manager with a custom ``Deserializable`` of your own choice.
func custom<T: Deserializable>(_ decoder: T) -> TypedRequestManager<T.Object>
/// Custom request manager which can be used to create a request manager with a custom ``Deserializable`` of your own choice.
func customOptional<T: Deserializable>(_ type: T) -> TypedRequestManager<T.Object?>
}
Task {
let address: Address = "www.apple.com"
let manager = SmartRequestManager.create()
let result = await manager.decodable.request(TestInfo.self, address: address)
switch result {
case .success(let obj):
// do something with response
case .failure(let error):
// do something with error
}
}
或
Task {
let address: Address = "www.apple.com"
let manager = SmartRequestManager.create()
manager.decodable.request(TestInfo.self, address: address) { result in
switch result {
case .success(let obj):
// do something with response
case .failure(let error):
// do something with error
}
}
.detach().deferredStart()
}
或
Task {
let address: Address = "www.apple.com"
let manager = SmartRequestManager.create()
let result = await manager.request(address: address).decodeAsync(TestInfo.self)
switch result {
case .success(let obj):
// do something with response
case .failure(let error):
// do something with error
}
}
或
let address: Address = "www.apple.com"
let manager = SmartRequestManager.create()
manager.request(address: address).decode(TestInfo.self).complete { result in
switch result {
case .success(let obj):
// do something with response
case .failure(let error):
// do something with error
}
}
.detach().deferredStart()
使用您自己的自定义可解码类型自定义您自己的网络
/// Custom decodable protocol for decoding data from response with specified keyPath
protocol KeyPathDecodable<Response> {
associatedtype Response: Decodable
static var keyPath: [String] { get }
}
extension SmartRequestManager {
func keyPathed<T: KeyPathDecodable>(_ type: T.Type = T.self) -> TypedRequestManager<T.Response?> {
return custom(KeyPathDecodableContent<T>())
}
}
private struct KeyPathDecodableContent<T: KeyPathDecodable>: Deserializable {
func decode(with data: RequestResult, parameters: Parameters) -> Result<T.Response?, Error> {
if let error = data.error {
return .failure(error)
} else if let data = data.body {
if data.isEmpty {
return .failure(RequestDecodingError.emptyResponse)
}
do {
let obj = try data.decode(T.Response.self, keyPath: T.keyPath)
return .success(obj)
} catch {
return .failure(error)
}
} else {
return .success(nil)
}
}
}