无法将日期字符串转换为通过 JSONDecoder 通过 json 响应接收的日期格式
Unable to convert date string to Date format received through json response via JSONDecoder
我收到 'M/d/yy' 格式的日期(例如 21 年 8 月 13 日),我正在使用 JSONDecoder 将数据解码为预期模型。
struct Model: Codable {
let submodel: SubModel
}
struct SubModel: Codable {
let item1, item2: [Date: Int] // I used [String: Int] and it works but I don't want to write an
} // additional method to do something that if possible can be
// done easily
如果我使用 [String: Int]
格式,我可以让它工作,但如果我使用 [Date: Int]
,它就不能工作。我用解码器的dateEncodingStrategy
设置自定义策略
makeGetRequest(url: url) { data in
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom({ decoder in
let formatter = DateFormatter()
let container = try decoder.singleValueContainer()
let dateString = try container.decode(String.self)
formatter.dateFormat = "M/d/yy"
if let date = formatter.date(from: dateString) {
return date
}
throw DecodingError.dataCorruptedError(in: container,
debugDescription: "Cannot decode date string \(dateString)")
})
let responseData = try decoder.decode(MainModel.self, from: data)
success(responseData)
} catch (let error) {
debugPrint("Error decoding data: \(error.localizedDescription)")
failure(error.localizedDescription)
}
}
我从服务器获得的 json 格式的示例响应是
{
"submodel": {
"item1": {
"8/7/21": 1,
"8/8/21": 2,
"8/9/21": 3
},
"item2": {
"8/7/21": 11,
"8/8/21": 12,
"8/9/21": 13
}
}
}
我收到错误消息“无法读取数据,因为它的格式不正确。”
感谢任何帮助
除了为您的 SubModel 结构创建自定义解码器外,我认为您别无选择:
extension SubModel {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let dictionary1 = try container.decode([String:Int].self, forKey: .item1)
let dictionary2 = try container.decode([String:Int].self, forKey: .item2)
let formatter = DateFormatter()
formatter.locale = .init(identifier: "en_US_POSIX")
formatter.dateFormat = "M/d/yy"
item1 = dictionary1.reduce(into: [:], { result, kv in
guard let date = formatter.date(from: kv.key) else { return }
result[date] = kv.value
})
item2 = dictionary2.reduce(into: [:], { result, kv in
guard let date = formatter.date(from: kv.key) else { return }
result[date] = kv.value
})
}
}
我收到 'M/d/yy' 格式的日期(例如 21 年 8 月 13 日),我正在使用 JSONDecoder 将数据解码为预期模型。
struct Model: Codable {
let submodel: SubModel
}
struct SubModel: Codable {
let item1, item2: [Date: Int] // I used [String: Int] and it works but I don't want to write an
} // additional method to do something that if possible can be
// done easily
如果我使用 [String: Int]
格式,我可以让它工作,但如果我使用 [Date: Int]
,它就不能工作。我用解码器的dateEncodingStrategy
设置自定义策略
makeGetRequest(url: url) { data in
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom({ decoder in
let formatter = DateFormatter()
let container = try decoder.singleValueContainer()
let dateString = try container.decode(String.self)
formatter.dateFormat = "M/d/yy"
if let date = formatter.date(from: dateString) {
return date
}
throw DecodingError.dataCorruptedError(in: container,
debugDescription: "Cannot decode date string \(dateString)")
})
let responseData = try decoder.decode(MainModel.self, from: data)
success(responseData)
} catch (let error) {
debugPrint("Error decoding data: \(error.localizedDescription)")
failure(error.localizedDescription)
}
}
我从服务器获得的 json 格式的示例响应是
{
"submodel": {
"item1": {
"8/7/21": 1,
"8/8/21": 2,
"8/9/21": 3
},
"item2": {
"8/7/21": 11,
"8/8/21": 12,
"8/9/21": 13
}
}
}
我收到错误消息“无法读取数据,因为它的格式不正确。”
感谢任何帮助
除了为您的 SubModel 结构创建自定义解码器外,我认为您别无选择:
extension SubModel {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let dictionary1 = try container.decode([String:Int].self, forKey: .item1)
let dictionary2 = try container.decode([String:Int].self, forKey: .item2)
let formatter = DateFormatter()
formatter.locale = .init(identifier: "en_US_POSIX")
formatter.dateFormat = "M/d/yy"
item1 = dictionary1.reduce(into: [:], { result, kv in
guard let date = formatter.date(from: kv.key) else { return }
result[date] = kv.value
})
item2 = dictionary2.reduce(into: [:], { result, kv in
guard let date = formatter.date(from: kv.key) else { return }
result[date] = kv.value
})
}
}