Home > Net >  How to use the value from a decoded struct that has an enum type value with custom initializers?
How to use the value from a decoded struct that has an enum type value with custom initializers?

Time:12-15

I have an API response that returns a JSON field with inconsistent types. Hence, I went to https://www.quicktype.io for some help and found a model.

Here is the model part where I have an issue:

struct MyModel: Codable {
    let id: ID?
}

enum ID: Codable {
    case integer(Int)
    case string(String)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode(Int.self) {
            self = .integer(x)
            return
        }
        if let x = try? container.decode(String.self) {
            self = .string(x)
            return
        }
        throw DecodingError.typeMismatch(ID.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for ID"))
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .integer(let x):
            try container.encode(x)
        case .string(let x):
            try container.encode(x)
        }
    }
}

I have a fully decoded response and when I try to print the value, I get something like:

Optional(MyApp.ID.integer(27681250))

OR

Optional(MyApp.ID.string(27681250))

I am doing so by:

print(modelData?.id)

I want to access the exact value I get but I am unable to do so. I have tried casting it into other types but it is not helping. Any help is appreciated. Thanks.

CodePudding user response:

There are a number of different ways you could do this. All of them are explained in The Swift Programming Language book in the Enumerations section.

Here is just one of the ways...

func example(id: ID) {
    switch id {
    case let .integer(value):
        <#code#>
    case let .string(value):
        <#code#>
    }
}
  • Related