将未知的可枚举枚举值解码为默认值 [英] Decoding unknown Encodable enum values to a default

查看:114
本文介绍了将未知的可枚举枚举值解码为默认值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须反序列化这样的JSON字符串:

I have to deserialize a JSON string like this:

{ "name" : "John Smith", "value" : "someValue" }

在Swift 4中,其中值"应该是一个枚举,整个对象是一个像这样的结构:

in Swift 4, where "value" should be a enum and the whole object is a struct like:

struct MyType {
    name: String?
    value: Value?
}

在将来的某个时刻,后端可能会添加新的枚举值,因此我认为进行一些回退是很明智的.

At some point in the future, there might be new enum values added in the backend so I thought it would be smart to have some fallback.

我以为我可以创建像这样的枚举

I thought I could create a enum like

enum Value {
    case someValue
    case someOtherValue
    case unknown(value: String)
}

但是我只是无法解决如何反序列化该枚举并使它正常工作的问题.以前,我只是使用String枚举,但是反序列化未知值会引发错误.

but I just can't wrap my head around how to deserialize that enum and make it work. Previously I simply used a String enum, but deserializing unknown values throws errors.

是否有一种简单的方法可以完成该工作,还是应该将值反序列化为String并使用switch语句在结构中创建自定义getter以返回其中一种情况(可能甚至不在结构本身中,在我看来模型)?

Is there a simple way to make that work or should I deserialize the value as a String and create a custom getter in the struct with a switch statement to return one of the cases (probably not even in the struct itself but in my view model)?

推荐答案

您可以实现init(from decoder: Decoder)encode(to encoder: Encoder)并显式处理每种情况,即

You can implement init(from decoder: Decoder) and encode(to encoder: Encoder) and handle every case explicitly, i.e.

struct MyType: Codable
{
    var name: String?
    var value: Value?

    enum CodingKeys: String, CodingKey
    {
        case name
        case value
    }

    init(from decoder: Decoder) throws
    {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        name = try values.decode(String.self, forKey: .name)
        let strValue = try values.decode(String.self, forKey: .value)
        //You need to handle every case explicitly
        switch strValue
        {
        case "someValue":
            value = Value.someValue
        case "someOtherValue":
            value = Value.someOtherValue
        default:
            value = Value.unknown(value: strValue)
        }
    }

    func encode(to encoder: Encoder) throws
    {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(name, forKey: .name)
        if let val = value
        {
            //You need to handle every case explicitly
            switch val
            {
            case .someValue, .someOtherValue:
                try container.encode(String(describing: val), forKey: .value)
            case .unknown(let strValue):
                try container.encode(strValue, forKey: .value)
            }
        }
    }
}

enum Value
{
    case someValue
    case someOtherValue
    case unknown(value: String)
}

这篇关于将未知的可枚举枚举值解码为默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆