2

For example my JSON looks like so:

{ 
   createdAt = "2018-06-13T12:38:22.987Z"  
}

My Struct looks like so:

struct myStruct {
    let createdAt: Date
}

Decode like so:

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601

When I am decoding I get this error:

failed to decode, dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "results", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "createdAt", intValue: nil)], debugDescription: "Expected date string to be ISO8601-formatted.", underlyingError: nil))

I understand it says that the string was expected to be ISO8601 formatted, but isn't it?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
farhan
  • 335
  • 2
  • 13
  • The standard ISO8601 format doesn't include milliseconds. – rmaddy Jun 13 '18 at 22:32
  • @rmaddy I see, is there a workaround for this? – farhan Jun 13 '18 at 22:34
  • `JSONDecoder` includes the option to provide a custom `DateFormatter` object. Create a custom DateFormatter with the desired format. Use your sample date string to test it, and then install it in the `JSONDecoder`. – Duncan C Jun 13 '18 at 22:38
  • possible duplicate of https://stackoverflow.com/a/46538676/2303865 – Leo Dabus Jun 13 '18 at 22:54
  • @farhan note that it is Swift naming convention to name your structures starting with an uppercase letter you might also be interested in https://stackoverflow.com/questions/46458487/how-to-convert-a-date-string-with-optional-fractional-seconds-using-codable-in-s – Leo Dabus Jun 13 '18 at 23:01

1 Answers1

11

The standard ISO8601 date format doesn't include fractional seconds so you need to use a custom date formatter for the date decoding strategy.

let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(dateFormatter)
rmaddy
  • 314,917
  • 42
  • 532
  • 579