Cleaner Way to Decode Missing JSON Keys?

I have a Codable class that looks like this:

import Foundation

struct MyClass: Decodable {
    let name: String
    let time: Date
    let sometimesPresent1: Double?
    let sometimesPresent2: Double?
    let sometimesPresent3: Double?

    enum DecodingKeys: String, CodingKey {
        case name, time, sometimesPresent1, sometimesPresent2, sometimesPresent3
    }

    public init(from decoder: Decoder) throws {
        self.time = Date()
        let container = try decoder.container(keyedBy: DecodingKeys.self)
        name = try container.decode(String.self, forKey: .name)
        // TODO: Is there any cleaner way to write the below?
        do { // These keys are sometimes altogether missing from the JSON returned by the exchange
            self.sometimesPresent1 = try container.decode(Double?.self, forKey: .sometimesPresent1)
        } catch {
            self.sometimesPresent1 = nil
        }
        do {
            self.sometimesPresent2 = try container.decode(Double?.self, forKey: .sometimesPresent2)
        } catch {
            self.sometimesPresent2 = nil
        }
        do {
            self.sometimesPresent3 = try container.decode(Double?.self, forKey: .sometimesPresent3)
        } catch {
            self.sometimesPresent3 = nil
        }
    }
}

The keys sometimesPresent 1, 2, and 3 are keys that are sometimes provided in the data and sometimes missing altogether. It's also possible the key will be present with the value null.

Is there any cleaner way to deal with keys that may or may not be present in the JSON? My actual use case has 5 such keys so the code becomes very verbose with five do/catch statements stacked on top of one another.

This is what decodeIfPresent is designed to handle.

1 Like

Ah, that's it exactly, thank you!

Doc here.

Terms of Service

Privacy Policy

Cookie Policy