61 lines
1.5 KiB
Swift
61 lines
1.5 KiB
Swift
//
|
|
// 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?
|
|
}
|