In Bite 315 we started looking at the new Codable
protocol in Swift 4. Today we'll learn how to work with Date
types when encoding and decoding. Let's dive in.
We'll start with another simple struct:
struct Spaceship : Codable {
var name: String
var createdAt: Date
}
Then, we'll create one and encode it into JSON to see what it looks like:
let ship = Spaceship(
name: "Skyhopper",
createdAt: Date()
)
let encoder = JSONEncoder()
if let data = try? encoder.encode(ship) {
print(String(data: data, encoding: .utf8)!)
}
This prints:
{
"name":"Skyhopper",
"createdAt":524735194.61138701
}
There's a lot more than meets the eye here though. That JSONEncoder
we created has some incredibly helpful properties on it.
The one we want is .dateEncodingStrategy
. Yep, it's a Swift enum with all sorts of goodies inside. Let's check them out.
We've already seen the default option, which is called .deferredToDate
.
Another great one is .iso8601
:
{
"name":"Skyhopper",
"createdAt":"2017-08-18T07:50:53Z"
}
Super neat to see that built in to the system in such a clean way.
Decoders have a similar property as well.
We've all had to decode some crazy date format from an HTTP API before. Now it's (hopefully) a little less painful.
Let's try decoding a funky format.
All we need to do is use the .formatted(DateFormatter)
value for our JSONDecoder
's .dateDecodingStrategy
property.
We'll give it this JSON to decode:
{
"name":"Skyhopper",
"createdAt":"Friday, Aug 18, 2017"
}
Then, we'll set up our decoder and formatter:
let decoder = JSONDecoder()
let formatter = DateFormatter()
formatter.dateFormat = "EEEE, MMM d, yyyy"
decoder.dateDecodingStrategy = .formatted(formatter)
let data = jsonString.data(using: .utf8)!
try? decoder.decode(Spaceship.self, from: data)
Which decodes to our struct as expected:
Spaceship(
name: "Skyhopper",
createdAt: 2017-08-18 05:00:00 +0000
)
Neat!
That's all for now. Happy coding!