我在用Swift将json解码成可编码模型时遇到了一些问题。 从服务器获得的json响应如下所示
{
"code": 200,
"data": {
"Australia": {
"address": "1111",
"port": "443",
"proto": "udp",
"country": "au"
},
"Australia udp": {
"address": "2222",
"port": "443",
"proto": "udp",
"country": "au"
},
"Vietnam TCP": {
"address": "3333",
"port": "443",
"proto": "tcp",
"country": "vn"
},
"status": "1"
}
}
现在我找到了其他关于如何解码简单数据类型的帖子,但是我没有找到解码复杂数据类型的帖子! 到目前为止我所做的就是这个模型
struct ListServers: Codable {
let code: Int
let data: [String: ListServersData]
}
enum ListServersData: Codable {
case string(String)
case innerItem(ServerInfo)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
if let x = try? container.decode(ServerInfo.self) {
self = .innerItem(x)
return
}
throw DecodingError.typeMismatch(ListServersData.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for MyValue"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .string(let x):
try container.encode(x)
case .innerItem(let x):
try container.encode(x)
}
}
}
struct ServerInfo: Codable {
let address, port, proto, country: String
}
但这会抛出一个错误!!
我不确定如何解码,因为我有响应的附加状态
请尝试以下操作:
只需在某处设置一个json字符串
let json =
"""
{
"code": 200,
"data": {
"Australia": {
"address": "1111",
"port": "443",
"proto": "udp",
"country": "au"
},
"Australia udp": {
"address": "2222",
"port": "443",
"proto": "udp",
"country": "au"
},
"Vietnam TCP": {
"address": "3333",
"port": "443",
"proto": "tcp",
"country": "vn"
},
"status": "1"
}
}
"""
然后设置与上面相同的结构和枚举:
struct ListServers: Codable {
let code: Int
let data: [String: ListServersData]
}
enum ListServersData: Codable {
case string(String)
case innerItem(ServerInfo)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
if let x = try? container.decode(ServerInfo.self) {
self = .innerItem(x)
return
}
throw DecodingError.typeMismatch(ListServersData.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for MyValue"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .string(let x):
try container.encode(x)
case .innerItem(let x):
try container.encode(x)
}
}
}
struct ServerInfo: Codable {
let address, port, proto, country: String
}
然后像这样解码json:
let jsonData = json.data(using: .utf8)!
do {
let decoder = JSONDecoder()
let result = try decoder.decode(ListServers.self, from: jsonData)
print("Code: \(result.code)")
for (_, v) in result.data {
switch v {
case .string(let string):
print("Status: \(string)")
case .innerItem(let serverInfo):
print("Address: \(serverInfo.address)")
print("Port: \(serverInfo.port)")
print("Proto: \(serverInfo.proto)")
print("Country: \(serverInfo.country)")
}
print("=======================")
}
}
catch {
print(error)
}
这就是正确打印出来的内容:
Code: 200
Address: 3333
Port: 443
Proto: tcp
Country: vn
=======================
Address: 2222
Port: 443
Proto: udp
Country: au
=======================
Status: 1
=======================
Address: 1111
Port: 443
Proto: udp
Country: au
=======================