问题出在您的JSONDecoder日期DecodingStrategy中.默认策略称为deferredToDate
,这意味着它期待timeIntervalSinceReferenceDate
.您需要一个定制的日期格式来解析您的ISO8601日期格式.判断一下这个How to convert a date string with optional fractional seconds using Codable in Swift?.
只需创建一个包含和不包含小数秒的自定义DateForMatter is8601:
extension Formatter {
static let iso8601withFractionalSeconds: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"
return formatter
}()
static let iso8601: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
return formatter
}()
}
和一个自定义的日期解码策略:
extension JSONDecoder.DateDecodingStrategy {
static let customISO8601 = custom {
let container = try $0.singleValueContainer()
let string = try container.decode(String.self)
if let date = Formatter.iso8601withFractionalSeconds.date(from: string) ?? Formatter.iso8601.date(from: string) {
return date
}
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid date: \(string)")
}
}
现在,您可以正确设置JSONDecoder日期DecodingStrategy:
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .customISO8601
并使用该解码器解析您的JSON字符串.请注意,如果您使用Try?您正在丢弃应该用来调试问题的错误:
return try decoder.decode([User].self, from: json)
} catch {
print(error)
}