提问人:Nik 提问时间:1/28/2023 更新时间:1/29/2023 访问量:140
在 Swift 中使用 Codable 将 JSON 解析为对象数组而不是字典
Parse JSON as array of objects instead of dictionary using Codable in Swift
问:
我从 API 收到以下 JSON
{
"someProperty":"someValue",
"type":"type1",
"values":{
"first":"someValue",
"second":"someValue" // keys and values are always different !
}
}
我创建了模型来解析这个 JSON,它可以工作。
struct MyModel: Codable {
let someProperty: String
let type: SomeType
var values: [String: String]?
}
enum SomeType: Codable {
case type1, type2
}
但是我需要获取对象数组而不是字典。因为我需要以正确的顺序获取值。
我想要这样的东西:
struct MyModel: Codable {
let someProperty: String
let type: SomeType
var values: [Value]?
}
enum SomeType: Codable {
case type1, type2
}
struct Value: Codable {
let key: String
let value: String
}
而且我不明白我应该在我的代码中更改什么才能使这个模型正常工作。因为现在我收到错误“预期解码数组,但找到了字典。
有没有办法像我想要的那样解析 JSON? 有什么建议吗?也许是具有类似解析的代码示例
感谢您的时间和帮助!
答:
0赞
burnsi
1/28/2023
#1
创建自定义初始化。在其中解码字典并将其映射到您的数组中:Value
struct MyModel: Codable {
let someProperty: String
let type: SomeType
var values: [Value]?
enum CodingKeys: CodingKey{
case someProperty, type, values
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
someProperty = try container.decode(String.self, forKey: .someProperty)
type = try container.decode(SomeType.self, forKey: .type)
let dictionary = try container.decodeIfPresent([String:String].self, forKey: .values)
values = dictionary?.map{Value(key: $0.key, value: $0.value)}
}
}
评论
0赞
Nik
1/28/2023
谢谢,它有效!但是使用字典,我丢失了值数组中的正确顺序。有没有办法保持正确的顺序?
0赞
burnsi
1/28/2023
@Nik 否,默认情况下字典是未排序的。如果排序已知,您可以在映射后自行对它们进行排序。
0赞
Nik
1/28/2023
有没有办法只获取没有值的键数组?然后使用它们来访问字典中的值?像这样: let arrayOfKeys = try container.decodeIfPresent([String].self, forKey: .values)
0赞
burnsi
1/28/2023
@Nik 您唯一能做的就是提供自己的反序列化器。使用我在您的问题下链接的库作为基础。
评论
type
values
values
values