enum PostType: Decodable {
init(from decoder: Decoder) throws {
// What do i put here?
}
case Image
enum CodingKeys: String, CodingKey {
To extend on @Toka's answer, you may too add a raw representable value to the enum, and use the default optional constructor to build the enum without a switch
:
enum MediaType: String, Decodable {
case audio = "AUDIO"
case multipleChoice = "MULTIPLE_CHOICES"
case other
init(from decoder: Decoder) throws {
let label = try decoder.singleValueContainer().decode(String.self)
self = MediaType(rawValue: label) ?? .other
}
}
It may be extended using a custom protocol that allows to refactor the constructor:
protocol EnumDecodable: RawRepresentable, Decodable {
static var defaultDecoderValue: Self { get }
}
extension EnumDecodable where RawValue: Decodable {
init(from decoder: Decoder) throws {
let value = try decoder.singleValueContainer().decode(RawValue.self)
self = Self(rawValue: value) ?? Self.defaultDecoderValue
}
}
enum MediaType: String, EnumDecodable {
static let defaultDecoderValue: MediaType = .other
case audio = "AUDIO"
case multipleChoices = "MULTIPLE_CHOICES"
case other
}
It can also be easily extended for throwing an error if an invalid enum value was specified, rather than defaulting on a value. Gist with this change is available here: https://gist.github.com/stephanecopin/4283175fabf6f0cdaf87fef2a00c8128.
The code was compiled and tested using Swift 4.1/Xcode 9.3.