Swift编码:使用未知密钥解码字典

Swift编码:使用未知密钥解码字典,swift,codable,Swift,Codable,当您知道JSON数据的关键格式时,Codable非常有用。但是如果你不知道钥匙呢?我现在面临着这个问题 通常,我希望JSON数据按如下方式返回: { "id": "<123>", "data": [ { "id": "<id1>", "event": "<event_type>", "date": "<date>" }, { "id": "<id2>

当您知道JSON数据的关键格式时,
Codable
非常有用。但是如果你不知道钥匙呢?我现在面临着这个问题

通常,我希望JSON数据按如下方式返回:

{
"id": "<123>",
"data": [
    {
        "id": "<id1>",
        "event": "<event_type>",
        "date": "<date>"
    },
    {
        "id": "<id2>",
        "event": "<event_type>",
        "date": "<date>"
    },
]
}

这会引发一个错误:
对成员“decode(uuxy:forKey:)”的引用不明确。

对于您完全更改的问题,解决方案非常类似。您的结构只需在数组上方添加一个附加层。不需要任何自定义解码,甚至不需要任何编码键

请注意,您不能在编码表中使用
Any

let json="""
{
"id": "123",
"data": [
    { "<id1>": { "<event>": "2019-05-21T16:15:34-0400" } },
    { "<id2>": { "<event>": "2019-07-01T12:15:34-0400" } },
]
}
"""
struct SampleModel: Codable {
    let id: String
    let data: [[String: [String: Date]]]
}

var decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
do {
    let res = try decoder.decode(SampleModel.self, from: json.data(using: .utf8)!)
    print(res)
} catch {
    print(error)
}
let json=”“”
{
“id”:“123”,
“数据”:[
{“”:{“”:“2019-05-21T16:15:34-0400”},
{“”:{“”:“2019-07-01T12:15:34-0400”},
]
}
"""
结构示例模型:可编码{
let id:String
let数据:[[String:[String:Date]]
}
var decoder=JSONDecoder()
decoder.dateDecodingStrategy=.iso8601
做{
让res=try decoder.decode(SampleModel.self,from:json.data(使用:.utf8)!)
打印(res)
}抓住{
打印(错误)
}

原始问题的原始答案

由于有一个嵌套字典数组,其中没有固定的字典键,并且没有其他字段,因此可以将其作为普通数组进行解码

下面是一个例子:

let json="""
[
    { "<id1>": { "<event>": "2019-07-01T12:15:34-0400" } },
    { "<id2>": { "<event>": "2019-05-21T17:15:34-0400" } },
]
"""
var decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
do {
    let res = try decoder.decode([[String: [String: Date]]].self, from: json.data(using: .utf8)!)
    print(res)
} catch {
    print(error)
}
let json=”“”
[
{“”:{“”:“2019-07-01T12:15:34-0400”},
{“”:{“”:“2019-05-21T17:15:34-0400”},
]
"""
var decoder=JSONDecoder()
decoder.dateDecodingStrategy=.iso8601
做{
让res=try decoder.decode([[String:[String:Date]]].self,from:json.data(使用:.utf8)!)
打印(res)
}抓住{
打印(错误)
}

我编辑了我的问题,以说明为什么需要编写代码。有没有一种方法可以使用
init(来自解码器:解码器)中的
KeyedDecodingContainer
以这种方式进行解码。在得到答案后,您完全改变了要求。给我几分钟。这个问题现在不是只是一个重复的问题吗?@matt很可能是更新后的问题现在是另一个问题的重复,但我认为这个问题不适用,因为这里的答案不需要任何自定义的
init
。这是一个简单得多的案例。@rmaddy感谢您的更新!它的关键是在
Codable
中使用
Any
;看了你的回答后,有些事情现在看起来很明显。好吧,既然你已经完全改变了这个问题,我想说这只是(和其他许多问题)的重复。
let json="""
{
"id": "123",
"data": [
    { "<id1>": { "<event>": "2019-05-21T16:15:34-0400" } },
    { "<id2>": { "<event>": "2019-07-01T12:15:34-0400" } },
]
}
"""
struct SampleModel: Codable {
    let id: String
    let data: [[String: [String: Date]]]
}

var decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
do {
    let res = try decoder.decode(SampleModel.self, from: json.data(using: .utf8)!)
    print(res)
} catch {
    print(error)
}
let json="""
[
    { "<id1>": { "<event>": "2019-07-01T12:15:34-0400" } },
    { "<id2>": { "<event>": "2019-05-21T17:15:34-0400" } },
]
"""
var decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
do {
    let res = try decoder.decode([[String: [String: Date]]].self, from: json.data(using: .utf8)!)
    print(res)
} catch {
    print(error)
}