雨燕可解码JSON字典异构阵列
问题描述:
我有一些的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
]
]
}
的问题是,“钥匙”将是不同的,每次和“值”中包含的异质字符串数组(应该转换为日期)和Ints。
有没有办法使用Swift的可解码协议来将它变成对象?
这里是它可能被解码为一个结构,
struct MyJSONData: Decodable {
var myInfo: Dictionary<String, [[Any]]>?
...
}
但是,如果有更好的方法来构造结构而言,我所有的耳朵!
在此先感谢。
答
我相当确定你的情况类似于我最近发布的问题:Flattening JSON when keys are known only at runtime。
如果是这样,你可以采用如下方案:
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
答
我与编码的JSON数组像你这样的异构数据的API时,但即使是为了列之前不知道:(
一般来说,我强烈建议不要将数据存储在异构数组中。您将很快忘记哪个索引代表什么属性,更不用说常量会返回一个前进。相反,当你从数组中解码时,建立一个数据模型来存储它。
另一件需要注意的事情是,你的日期不是JSONDecoder
预期的默认值。它期望ISO 8601格式(yyyy-MM-ddTHH:mm:ssZ
),而日期字符串中缺少时间分量。你可以告诉JSONDecoder
什么通过提供定制DateFormatter
做:
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)
不能使用任何/ AnyObject。你的数据结构是否稳定?我的意思是,它会始终是一个字符串和一个Int顺序? – nathan
@nathan Any/AnyObject不符合Codable协议,所以这不会真的有所帮助。 –