使用 Decodable 解析数组
Parsing an array using Decodable
这是我的JSON,我正在尝试解析它并想了解容器概念。
{
"results": [
{
"type": "TEST",
"date": 1518633000000,
"slots": [
{
"startDatetime": 1518665400000,
"endDatetime": 1518667200000,
},
{
"startDatetime": 1518667200000,
"endDatetime": 1518669000000,
}
]
}
]
}
这就是我正在尝试使用我的代码。我还为 slots
确认了可解码协议。解析 Expected to decode Dictionary<String, Any> but found an array instead
时出现此错误。请给我使用 Decodable 协议覆盖的解决方案。
当解码器尝试解码结果时,此行发生错误。
struct Slots: Codable
{
var startDateTime: UInt64?
var endDateTime: UInt64?
}
struct Results:Codable {
var type:String?
var date:UInt64?
var slots:[Slots]?
private enum CodingKeys:String, CodingKey
{
case type
case date
case slots
}
private enum ResultsKey: String, CodingKey
{
case results
}
public init(from decoder:Decoder) throws
{
let values = try decoder.container(keyedBy: ResultsKey.self)
let resultsValues = try values.nestedContainer(keyedBy: CodingKeys.self, forKey: .results)
type = try resultsValues.decode(String.self, forKey: .type)
date = try resultsValues.decode(UInt64.self, forKey: .date)
slots = try resultsValues.decode([Slots].self, forKey: .slots)
}
}
if let data = response.data {
// init the decoder here
let decoder = JSONDecoder()
// Error occurs here
let results = try! decoder.decode(Results.self, from: data)
}
这是典型的错误。您忘记了根(最外层)对象,即键为 results
.
的字典
您不需要任何编码密钥或初始化器,您可以通过添加一行
将时间戳直接解码为 Date
struct Root : Decodable {
let results : [Result]
}
struct Result : Decodable {
let type : String
let date : Date
let slots: [Slot]
}
struct Slot : Decodable {
let startDatetime, endDatetime : Date
}
假设 data
是 Data
格式的 JSON 字符串
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .millisecondsSince1970
let result = try decoder.decode(Root.self, from: data)
print(result)
} catch { print(error) }
并且不要粗心大意地将每个 属性 声明为可选的。
这是我的JSON,我正在尝试解析它并想了解容器概念。
{
"results": [
{
"type": "TEST",
"date": 1518633000000,
"slots": [
{
"startDatetime": 1518665400000,
"endDatetime": 1518667200000,
},
{
"startDatetime": 1518667200000,
"endDatetime": 1518669000000,
}
]
}
]
}
这就是我正在尝试使用我的代码。我还为 slots
确认了可解码协议。解析 Expected to decode Dictionary<String, Any> but found an array instead
时出现此错误。请给我使用 Decodable 协议覆盖的解决方案。
当解码器尝试解码结果时,此行发生错误。
struct Slots: Codable
{
var startDateTime: UInt64?
var endDateTime: UInt64?
}
struct Results:Codable {
var type:String?
var date:UInt64?
var slots:[Slots]?
private enum CodingKeys:String, CodingKey
{
case type
case date
case slots
}
private enum ResultsKey: String, CodingKey
{
case results
}
public init(from decoder:Decoder) throws
{
let values = try decoder.container(keyedBy: ResultsKey.self)
let resultsValues = try values.nestedContainer(keyedBy: CodingKeys.self, forKey: .results)
type = try resultsValues.decode(String.self, forKey: .type)
date = try resultsValues.decode(UInt64.self, forKey: .date)
slots = try resultsValues.decode([Slots].self, forKey: .slots)
}
}
if let data = response.data {
// init the decoder here
let decoder = JSONDecoder()
// Error occurs here
let results = try! decoder.decode(Results.self, from: data)
}
这是典型的错误。您忘记了根(最外层)对象,即键为 results
.
您不需要任何编码密钥或初始化器,您可以通过添加一行
将时间戳直接解码为Date
struct Root : Decodable {
let results : [Result]
}
struct Result : Decodable {
let type : String
let date : Date
let slots: [Slot]
}
struct Slot : Decodable {
let startDatetime, endDatetime : Date
}
假设 data
是 Data
格式的 JSON 字符串
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .millisecondsSince1970
let result = try decoder.decode(Root.self, from: data)
print(result)
} catch { print(error) }
并且不要粗心大意地将每个 属性 声明为可选的。