假设我们有以下结构:
struct TestCod: Codable {
var txt = ""
var date = Date()
}
如果我们期待两种相似格式的 JSON,我们如何处理解码?
JSON A:
{
"txt":"stack",
"date":589331953.61679399
}
JSON B:
{
"txt":"overflow",
"date":"2019-09-05"
}
如我在评论中已经提到的可能重复的帖子所示,您需要创建自定义日期解码策略:
首先创建日期格式化程序以解析日期字符串(请注意,这假设您的日期是本地时间,如果您需要 UTC 时间或服务器时间,则需要相应地设置格式化程序时区属性(:
extension Formatter {
static let yyyyMMdd: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
}
然后创建自定义解码策略,以尝试可能需要的所有可能的日期解码策略:
extension JSONDecoder.DateDecodingStrategy {
static let deferredORyyyyMMdd = custom {
let container = try $0.singleValueContainer()
do {
return try Date(timeIntervalSinceReferenceDate: container.decode(Double.self))
} catch {
let string = try container.decode(String.self)
if let date = Formatter.yyyyMMdd.date(from: string) {
return date
}
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid date: (string)")
}
}
}
游乐场测试:
struct TestCod: Codable {
let txt: String
let date: Date
}
let jsonA = """
{
"txt":"stack",
"date":589331953.61679399
}
"""
let jsonB = """
{
"txt":"overflow",
"date":"2019-09-05"
}
"""
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .deferredORyyyyMMdd
let decodedJSONA = try! decoder.decode(TestCod.self, from: Data(jsonA.utf8))
decodedJSONA.date // "Sep 4, 2019 at 8:19 PM"
let decodedJSONB = try! decoder.decode(TestCod.self, from: Data(jsonB.utf8))
decodedJSONB.date // "Sep 5, 2019 at 12:00 AM"