Codable/Decodable 应该用字符串解码数组
Codable/Decodable should decode Array with Strings
为什么名称数组没有解码?
为 Playground 准备,只需将其粘贴到您的 playground
import Foundation
struct Country : Decodable {
enum CodingKeys : String, CodingKey {
case names
}
var names : [String]?
}
extension Country {
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
names = try values.decode([String]?.self, forKey: .names)!
}
}
let json = """
[{
"names":
[
"Andorre",
"Andorra",
"アンドラ"
]
},{
"names":
[
"United Arab Emirates",
"Vereinigte Arabische Emirate",
"Émirats Arabes Unis",
"Emiratos Árabes Unidos",
"アラブ首長国連邦",
"Verenigde Arabische Emiraten"
]
}]
""".data(using: .utf8)!
let decoder = JSONDecoder()
do {
let countries = try decoder.decode([Country].self, from: json)
countries.forEach { print([=11=]) }
} catch {
print("error")
}
您已将 names
定义为 Country
的 可选 属性。
如果您的意图是此密钥可能不存在于 JSON
然后使用 decodeIfPresent
:
extension Country {
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
names = try values.decodeIfPresent([String].self, forKey: .names)
}
}
此方法returns nil
如果容器没有与键关联的值,或者值为空。
但实际上你可以省略你的自定义 init(from decoder: Decoder)
实现(和 enum CodingKeys
),因为这是默认行为并且将
自动合成。
备注:隐式变量error
定义在任何catch
子句中,
所以
} catch {
print(error.localizedDescription)
}
可能比 print("error")
提供更多信息(尽管不是
在这种特殊情况下)。
为什么名称数组没有解码?
为 Playground 准备,只需将其粘贴到您的 playground
import Foundation
struct Country : Decodable {
enum CodingKeys : String, CodingKey {
case names
}
var names : [String]?
}
extension Country {
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
names = try values.decode([String]?.self, forKey: .names)!
}
}
let json = """
[{
"names":
[
"Andorre",
"Andorra",
"アンドラ"
]
},{
"names":
[
"United Arab Emirates",
"Vereinigte Arabische Emirate",
"Émirats Arabes Unis",
"Emiratos Árabes Unidos",
"アラブ首長国連邦",
"Verenigde Arabische Emiraten"
]
}]
""".data(using: .utf8)!
let decoder = JSONDecoder()
do {
let countries = try decoder.decode([Country].self, from: json)
countries.forEach { print([=11=]) }
} catch {
print("error")
}
您已将 names
定义为 Country
的 可选 属性。
如果您的意图是此密钥可能不存在于 JSON
然后使用 decodeIfPresent
:
extension Country {
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
names = try values.decodeIfPresent([String].self, forKey: .names)
}
}
此方法returns nil
如果容器没有与键关联的值,或者值为空。
但实际上你可以省略你的自定义 init(from decoder: Decoder)
实现(和 enum CodingKeys
),因为这是默认行为并且将
自动合成。
备注:隐式变量error
定义在任何catch
子句中,
所以
} catch {
print(error.localizedDescription)
}
可能比 print("error")
提供更多信息(尽管不是
在这种特殊情况下)。