I have a json file being parsed using JSONDecoder(). However, I receive the variable timestamp of type Date in iso-8601-format ("yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX") but on my view, I want to display it in a custom format: "dd/mm/yy HH:mm:ss".
I have written the following code, but I get nil for timestamp and furthermore I assume "date" is not the correct type to use when timestamp comes in iso-8601 format:
Error json: typeMismatch(Swift.Double, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "timestamp", intValue: nil)], debugDescription: "Expected to decode Double but found a string/data instead.", underlyingError: nil))
swift4
import UIKit
enum Type : String, Codable {
case organizational, planning
}
// structure from json file
struct News: Codable{
let type: Type
let timestamp: Date //comes in json with ISO-8601-format
let title: String
let message: String
enum CodingKeys: String, CodingKey { case type, timestamp, title, message}
let dateFormatter : DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yy HH:mm:ss" // change format ISO-8601 to dd/MM/yy HH:mm:ss
return formatter
}()
var dateString : String {
return dateFormatter.string(from:timestamp) // take timestamp variable of type date and make it a string -> lable.text
}
}
When you are decoding a Date
the decoder expects an UNIX timestamp (a Double
) by default, this is what the error message tells you.
However you can indeed decode an ISO8601 string as Date
if you add the decoder.dateDecodingStrategy = .iso8601
but this decodes only standard ISO8601 strings without milliseconds.
There are two options:
Add a formatted
dateDecodingStrategy
with a DateFormatter
.
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(dateFormatter)
try decoder.decode(...
Declare timestamp
as
let timestamp: String
and convert the string back and forth with two formatters or two date formats in dateString
.