Swift
Enum
Decodable
JSON Parsing
Swift Programming

How do I make an enum Decodable in Swift?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

In Swift, enums are a common data structure used to represent a group of related values in a type-safe way. When dealing with JSON data, you might need to make your enums conform to the Decodable protocol so they can be easily parsed from JSON. This article will guide you through the process of making an enum Decodable in Swift, with detailed examples, technical explanations, and additional considerations.

What is Decodable?

Decodable is a protocol in Swift's Codable framework that allows for easy parsing of data formats such as JSON into Swift types. By conforming to Decodable, you provide implementations to decode instances of your data types.

Basics of Enums in Swift

Enums in Swift define a common type for a group of related values. They can be very simple, like lists of possible states, but can also carry associated values, making them more complex:

swift
1enum NetworkStatus {
2    case connected
3    case disconnected
4    case connecting
5}

Making an Enum Decodable

To make an enum Decodable, you need to extend it to conform to the Decodable protocol. This involves implementing the init(from decoder: Decoder) initializer. There are mainly two types of enums you may work with: those without associated values and those with associated values.

Enum without Associated Values

Consider an enum representing different fruits:

swift
1enum Fruit: String, Decodable {
2    case apple
3    case orange
4    case banana
5}

Here, Fruit enum automatically conforms to Decodable by also conforming to the RawRepresentable protocol, since its raw value type (a String) is Decodable.

Enum with Associated Values

Enums with associated values require a custom initializer to conform to Decodable:

swift
1enum Measurement {
2    case weight(Double)
3    case height(Double)
4    case age(Int)
5}
6
7extension Measurement: Decodable {
8    enum CodingKeys: String, CodingKey {
9        case type
10        case value
11    }
12    
13    enum MeasurementType: String, Decodable {
14        case weight
15        case height
16        case age
17    }
18    
19    init(from decoder: Decoder) throws {
20        let container = try decoder.container(keyedBy: CodingKeys.self)
21        let type = try container.decode(MeasurementType.self, forKey: .type)
22        
23        switch type {
24        case .weight:
25            let value = try container.decode(Double.self, forKey: .value)
26            self = .weight(value)
27        case .height:
28            let value = try container.decode(Double.self, forKey: .value)
29            self = .height(value)
30        case .age:
31            let value = try container.decode(Int.self, forKey: .value)
32            self = .age(value)
33        }
34    }
35}

Handling Invalid or Missing Data

Decoding can fail if the data doesn't contain the expected values or types. You should handle these cases gracefully, either by providing default values or by throwing decoding errors when invalid data is encountered.

Example: Using Decodable Enum in a Model

Here’s how you might use a Decodable enum in a larger data model:

swift
1struct Human: Decodable {
2    let name: String
3    let attribute: Measurement
4}
5
6let jsonData = """
7{
8    "name": "Alice",
9    "attribute": {
10        "type": "height",
11        "value": 170.5
12    }
13}
14""".data(using: .utf8)!
15
16do {
17    let human = try JSONDecoder().decode(Human.self, from: jsonData)
18    print(human)
19} catch {
20    print("Failed to decode JSON: \(error)")
21}

Summary

To facilitate quick understanding, here's a table summarizing the key points on making enums Decodable:

Key PointsDescription
Decodable ProtocolAllows parsing JSON into Swift types.
Enum with Raw ValuesCan automatically conform if raw type is Decodable.
Enums with Associated ValuesRequires custom implementation of init(from decoder: Decoder).
Handling ErrorsUse try-catch to manage decoding errors.
JSONDecoder ExampleDemonstrated decoding JSON into models.

Additional Considerations

  • Testing: Always test your decoding, as JSON structure might change.
  • Error Handling: Swift provides various error handling mechanisms (try-catch) to ensure robustness.
  • Optional Values: Consider optional properties for cases where some JSON fields may or may not be present.

By carefully implementing and testing your decoding logic, you can ensure that your application robustly handles even complex JSON data structures using Swift's enums. This not only makes the code cleaner but also makes data handling more efficient and safer due to the type-safe nature of Swift.


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.