添加网络层并接入 v9 登录流程及单元测试
This commit is contained in:
60
suixinkan/Core/Networking/APIEnvelope.swift
Normal file
60
suixinkan/Core/Networking/APIEnvelope.swift
Normal file
@ -0,0 +1,60 @@
|
||||
//
|
||||
// APIEnvelope.swift
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// 后端统一响应包裹实体,承载业务 code、msg 和真实 data。
|
||||
struct APIEnvelope<T: Decodable>: Decodable {
|
||||
let data: T?
|
||||
let code: Int
|
||||
let msg: String?
|
||||
|
||||
/// 判断后端业务 code 是否代表成功。
|
||||
var isSuccess: Bool {
|
||||
code == 100000
|
||||
}
|
||||
|
||||
/// 后端统一 Envelope 的 JSON 字段映射。
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case data
|
||||
case code
|
||||
case msg
|
||||
}
|
||||
|
||||
/// 自定义解码逻辑,兼容成功响应、空 data 和 EmptyPayload。
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
code = try container.decodeIfPresent(Int.self, forKey: .code) ?? 0
|
||||
msg = try container.decodeIfPresent(String.self, forKey: .msg)
|
||||
|
||||
guard code == 100000 else {
|
||||
data = nil
|
||||
return
|
||||
}
|
||||
|
||||
guard container.contains(.data), try !container.decodeNil(forKey: .data) else {
|
||||
data = nil
|
||||
return
|
||||
}
|
||||
|
||||
if T.self == EmptyPayload.self {
|
||||
data = EmptyPayload() as? T
|
||||
return
|
||||
}
|
||||
|
||||
data = try container.decode(T.self, forKey: .data)
|
||||
}
|
||||
}
|
||||
|
||||
/// 空响应实体,用于表示接口成功但不返回业务 data。
|
||||
struct EmptyPayload: Codable {}
|
||||
|
||||
/// 错误响应实体,用于从 HTTP 错误体中提取服务端文案。
|
||||
struct ErrorEnvelope: Decodable {
|
||||
let code: Int?
|
||||
let msg: String?
|
||||
let message: String?
|
||||
let error: String?
|
||||
}
|
||||
Reference in New Issue
Block a user