I did a little refactoring to get ready for the search results view to handle recent selections. I thought about using some fancy Environment values, but opted to just pass some functions around so that I could reuse some views. Might revisit later.

Now I'm at a tricky part. I need to encode my media enums so that I can persist them when selected.

Media is an enum with associated values:

enum Media {

    case movie(Movie)
    case tvShow(TVShow)
    case person(Person)

}

I was struggling with figuring out how to encode the associated values correctly. Then it hit me, pass the Encoder to the encode function of each model:

func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    switch self {
        case .movie(let movie):
            try container.encode(MediaType.movie, forKey: .mediaType)
            try movie.encode(to: encoder)
        case .tvShow(let tvShow):
            try container.encode(MediaType.tvShow, forKey: .mediaType)
            try tvShow.encode(to: encoder)
        case .person(let person):
            try container.encode(MediaType.person, forKey: .mediaType)
            try person.encode(to: encoder)
    }
}

This also gives me the opportunity to set the mediaType so it will decode correctly. I was scared this was going to be a really difficult problem in Swift—again I'm new to Codable—but actually turned out to be pretty straightforward and clean!