让网络请求如流水一般
① PromiseKit
② PromiseKit/OMGHTTPURLRQ
③ Swift4 JSON 原生解析 Codable
④ 泛型 T
可以通过cocoapods进行安装
pod 'PromiseKit'
pod 'PromiseKit/OMGHTTPURLRQ'
简单实现请求操作的统一处理流程,如图所示
绿色部分,就是在请求时候统一“流”
Promise+Ex.swift
// MARK: - 后台基本返回对象
struct Result<T: Codable>:Codable {
var code: Int
var message: String
var timestamp: Int! //不确定存在的,可采用可选类型
var data:T?
}
// MARK: - 一些响应的错误
enum PMKResponseError: Error {
case status(code: Int, msg: String)
case loginValid
}
// MARK: - Promise+Ex
typealias Contents = (data: Data, response: URLResponse)
extension Promise where T == Contents {
func asObject<T: Codable>() -> Promise<T> {
return validate().isLoginValid().objectHandle().catchHandle()
}
}
// MARK: - 一些流水线操作
extension Promise where T == Contents {
/// 验证网络状况
private func validate() -> Promise<Contents> {
return map {
guard let response = $0.response as? HTTPURLResponse else { return $0 }
switch response.statusCode {
case 200..<300:
return $0
case let code:
throw PMKHTTPError.badStatusCode(code, $0.data, response)
}
}
}
/// 验证登录有效性
private func isLoginValid() -> Promise<Contents> {
return map {
// TODO: - 对应的登录失效判断处理
guard let response = $0.response as? HTTPURLResponse else { return $0 }
guard response.statusCode == 666 else { return $0 }
throw PMKResponseError.loginValid
}
}
/// 对象处理
private func objectHandle<T: Codable>() -> Promise<T> {
return map {
var res: Result<T>
do {
res = try JSONDecoder().decode(Result<T>.self, from: $0.data)
} catch {
throw error
}
guard res.code == 200 else {
throw PMKResponseError.status(code: res.code, msg: res.message)
}
guard let data = res.data else {
return try JSONDecoder().decode(T.self, from: $0.data)
}
return data
}
}
}
// MARK: - 捕获的错误状态处理
extension Promise where T:Codable {
private func catchHandle(policy: CatchPolicy = conf.catchPolicy) -> Promise<T> {
pipe {
if case .rejected(let error) = $0 {
switch error {
case let PMKHTTPError.badStatusCode(code, _, response):
// - 可进行网络错误提示操作
print("code: \(code), response: \(response)")
case PMKResponseError.loginValid:
// - 可进行跳转登录页操作
print("登录失效")
case let PMKResponseError.status(code, msg):
// - 可进行全局菊花操作
print("code: \(code), message: \(msg)")
default:
print(error)
}
}
}
return self
}
}
DemoApi.swift
/* model
struct ObjectData:Codable {
var useranme: String
var userId: Int
//...
}
struct ArrayData:Codable {
var id: Int
var avatar: String
//...
}
*/
Promise<Result> // data 为空时候,上面对象处理方法已做处理,返回自身
Promise<ObjectData> // data 为对象时候
Promise<[ArrayData]> // data 为数组时候
struct DemoApi {
static func getUserInfo(userid: Int) -> Promise<ObjectData> {
return URLSession.shared.GET(NetWorks.api + "/v3/user/\(userid)").asObject()
}
// ...
}
ViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
DemoApi.getUserInfo(userid: 123456).done { data in
print(data) // 如果是返回自身的话,可以data.code
}.catch { error in
print(error) //这里也可对上面绿色部分捕获错误进行处理
}
}