I have defined an enum
as follows:
enum Type: String, Codable {
case text = "text"
case image = "image"
case document = "document"
case profile = "profile"
case sign = "sign"
case inputDate = "input_date"
case inputText = "input_text"
case inputNumber = "input_number"
case inputOption = "input_option"
case unknown
}
that maps a JSON string property. The automatic serialization and deserialization works fine, but I found that if a different string is encountered, the deserialization fails.
Is it possible to define an unknown
case that maps any other available case?
This can be very useful, since this data comes from a RESTFul API that, maybe, can change in the future.
You can extend your Codable Type and assign a default value in case of failure:
Here's an alternative based on nayem's answer that offers a slightly more streamlined syntax by using optional binding of the inner
RawValues
initialization:If you are certain that all your existing enum case names match the underlying string values they represent, you could streamline
RawValue
to:...and
encode(to:)
to:Here's a practical example of using this, e.g., you want to model
SomeValue
that has a property you want to model as an enum:You have to implement the
init(from decoder: Decoder) throws
initializer and check for a valid value:You can drop the raw type for your
Type
and make unknown case that handles associated value. But this comes at a cost. You somehow need the raw values for your cases. Inspired from this and this SO answers I came up with this elegant solution to your problem.To be able to store the raw values, we will maintain another enum, but as private:
Move the
encoding
&decoding
part to extensions:Decodable part:
Encodable part:
Examples:
I just wrapped it in a container structure(because we'll be using JSONEncoder/JSONDecoder) as:
For values other than unknown case:
For values with unknown case: