Devlog: December 15, 2022
Was having a hard time with decoding some JSON. Was banging my head for like 30 mins. Turns out, I was simply trying to decode it as the wrong type—itself rather than a string 🤦🏻♂️.
I think I finally understand using an enum to decode values that could be multiple types. So in my case, results
is an array that can hold Movie
, TVShow
, or Person
. Can’t really throw in let results: [Movie | TVShow | Person]
like you can in TypeScript. So, I made Media
, which is an enum of movie
, tvShow
, and person
. Helpfully, each type of media has the key media_type
, so you know what you’re dealing with. When Media
is being decoded, we look for media_type
, and then based on that, create an enum with the correct associated type. Pretty cool. This is all pretty much stolen from an existing Swift TMDb library. Honestly, don’t know if I would’ve ever come up with this solution, and I doubt I explained it very clearly. But I like it, and I’m
not sure there are any other great solutions. When I get to the UI—which is taking me quite a while to get to…—I could use the enum to easily pick the correct View to use. Enums in Swift are powerful and I need to explore them more.
enum Media: Decodable {
case movie(Movie)
case tvShow(TVShow)
case person(Person)
private enum CodingKeys: String, CodingKey {
case mediaType
}
private enum MediaType: String, Decodable, Equatable {
case movie
case tvShow = "tv"
case person
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let mediaType = try container.decode(MediaType.self, forKey: .mediaType)
switch mediaType {
case .movie:
self = .movie(try Movie(from: decoder))
case .tvShow:
self = .tvShow(try TVShow(from: decoder))
case .person:
self = .person(try Person(from: decoder))
}
}
}