Swift - 从未包含在案例中的 json 字符串解码的枚举有一个未知的案例

emr*_*pun 0 enums json swift decodable

对于给定的 JSON,如下所示:

{
    "store": {
        "animals": [
            {
                "type": "dog"
            },
            {
                "type": "cat"
            }
        ]
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以用 enum 解析它,type如下所示:

final class AnimalStore: Decodable {
    let store: Store
}

extension AnimalStore {
    struct Store: Decodable {
        let animals: [Animal]
    }
}

extension AnimalStore.Store {
    struct Animal: Decodable {
        let type: AnimalType?
    }
}

extension AnimalStore.Store.Animal {
    enum AnimalType: String, Decodable {
        case dog = "dog"
        case cat = "cat"
        //case unknown = how such a case could be implemented?
    }
}
Run Code Online (Sandbox Code Playgroud)

而且因为它是可选的;如果typejson 中缺少键值对,它会正常工作。

但我想有另一种情况,让我们调用它,unknown以便如果任何给定的类型不是狗或猫(字符串是别的东西),类型将被初始化为未知。现在,如果给出了除狗或猫之外的类型,它会崩溃。

如何使用枚举实现除给定类型之外的其他类型的初始化?

换句话说,对于给定的类型,例如:"type": "bird"我想type被初始化为unknown.

jrt*_*ton 6

用字符串添加枚举大小写,你也可以使用"unknown".

要将不匹配的字符串转换为未知字符串,您必须init(from decoder: Decoder)在某个时候手动实现,无论是在您的 Animal 中还是在 AnimalType 中。我更喜欢使用 AnimalType,这样您就不必手动解码 Animal 的任何其他属性。

enum AnimalType: String, Decodable {
    case dog = "dog"
    case cat = "cat"
    case unknown = "unknown"

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let string = try container.decode(String.self)
        self = AnimalType(rawValue: string) ?? .unknown
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你在Animal,你需要这样的东西:

// Decode everything else...
type = try? decoder.decode(AnimalType.self, forKey: .type) ?? .unknown
Run Code Online (Sandbox Code Playgroud)