如何在 Swift 中使用具有自定义类型值的可解码协议?
How to use decodable protocol with custom type values in Swift?
根据我的要求,我有两种类型的回复:第一种:
{
"status": "success"
"data": {
"user_id": 2,
"user_name": "John"
}
}
第二个是:
{
"status": "error",
"data": [],
}
我正在使用这样的结构:
struct ValyutaListData:Decodable {
let status: String?
let data: [String]?
}
但是如果response是first type response,就会出错。因为在第一个类型中,响应数据不是数组。它是 Json 对象。然后我使用这样的结构:
struct ValyutaListData:Decodable {
let status: String?
let data: Persondata?
}
struct Persondata: Decodable{
let user_id: Int?
let user_name: String?
}
如果response是second type response,就会报错。动态类型 JSON 应该使用哪种结构?谢谢。
一个合理的解决方案是具有关联类型的枚举
struct User : Decodable {
let userId: Int
let userName: String
}
enum Result : Decodable {
case success(User), failure
enum CodingKeys: String, CodingKey { case status, data }
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let status = try container.decode(String.self, forKey: .status)
if status == "success" {
let userData = try container.decode(User.self, forKey: .data)
self = .success(userData)
} else {
self = .failure
}
}
}
并使用它
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(Result.self, from: data)
switch result {
case .success(let user): print(user)
case .failure: print("An error occurred")
}
} catch { print(error) }
根据我的要求,我有两种类型的回复:第一种:
{
"status": "success"
"data": {
"user_id": 2,
"user_name": "John"
}
}
第二个是:
{
"status": "error",
"data": [],
}
我正在使用这样的结构:
struct ValyutaListData:Decodable {
let status: String?
let data: [String]?
}
但是如果response是first type response,就会出错。因为在第一个类型中,响应数据不是数组。它是 Json 对象。然后我使用这样的结构:
struct ValyutaListData:Decodable {
let status: String?
let data: Persondata?
}
struct Persondata: Decodable{
let user_id: Int?
let user_name: String?
}
如果response是second type response,就会报错。动态类型 JSON 应该使用哪种结构?谢谢。
一个合理的解决方案是具有关联类型的枚举
struct User : Decodable {
let userId: Int
let userName: String
}
enum Result : Decodable {
case success(User), failure
enum CodingKeys: String, CodingKey { case status, data }
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let status = try container.decode(String.self, forKey: .status)
if status == "success" {
let userData = try container.decode(User.self, forKey: .data)
self = .success(userData)
} else {
self = .failure
}
}
}
并使用它
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(Result.self, from: data)
switch result {
case .success(let user): print(user)
case .failure: print("An error occurred")
}
} catch { print(error) }