具有异构数组的快速可解码 JSON 字典



我有一些JSON以以下格式返回,

{
"Random Word": [
[
"2017-08-10",
6
],
[
"2017-08-11",
6
],
[
"2017-08-15",
4
]
],
"Another Random Word": [
[
"2017-08-10",
4
],
[
"2017-08-11",
4
],
[
"2017-08-12",
1
],
[
"2017-08-14",
2
],
[
"2017-08-15",
4
],
[
"2017-08-16",
1
]
]
}

问题是"键"每次都会不同,并且"值"包含字符串(应转换为日期(和整数的异构数组。

有没有办法使用 Swift 的 Decodable 协议将其转换为对象?

这是一个结构,它可以解码为,

struct MyJSONData: Decodable {
var myInfo: Dictionary<String, [[Any]]>?
...
}

但是,如果有更好的方法来构建结构,我都听!

提前谢谢。

我相当确定您的情况类似于我最近发布的问题:当密钥仅在运行时已知时扁平化 JSON。

如果是这样,您可以使用以下解决方案:

struct MyJSONData: Decodable {
var dates = [Any]()
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
// Only use first item
let stringItem = try container.decode(String.self)
dates.append(stringItem)
let numberItem = try container.decode(Int.self)
dates.append(numberItem)
}
}
let decoded = try! JSONDecoder().decode([String : [MyJSONData]].self, from: jsonData).values
// Returns an Array of MyJSONData

工作解决方案:http://swift.sandbox.bluemix.net/#/repl/59949d74677f2b7ec84046c8

我正在使用一个 API,它使用像您这样的异构数据对 JSON 数组进行编码,但事先甚至不知道列的顺序:(

通常,我强烈建议不要将数据存储在异构数组中。你很快就会忘记什么索引代表什么属性,更不用说来回不断的强制转换了。相反,创建一个数据模型,以便在从数组解码时存储它。

需要注意的另一件事是,默认情况下,您的日期不是JSONDecoder期望的。它需要ISO 8601格式(yyyy-MM-ddTHH:mm:ssZ(,而日期字符串中缺少时间部分。您可以通过提供自定义DateFormatter来告诉JSONDecoder该怎么做:

struct WordData: Decodable {
var date: Date
var anInt: Int
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
self.date = try container.decode(Date.self)
self.anInt = try container.decode(Int.self)
}
}
var dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_us_POSIX")
dateFormatter.timeZone = TimeZone(identifier: "UTC")
dateFormatter.dateFormat = "yyyy-MM-dd"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(dateFormatter)
let words = try decoder.decode([String: [WordData]].self, from: jsonData)

相关内容

  • 没有找到相关文章

最新更新