一尘不染

Swift 4 Codable-Bool或String值

swift

寻找一些有关如何处理我最近遇到的情况的意见。

我一直在使用Swift 4s Codable取得成功,但今天发现了我没有想到的崩溃。我正在使用的API说,它boolean为key 返回a
manage_stock

我的存根结构如下:

struct Product: Codable {
    var manage_stock: Bool?
}

效果很好,问题在于API 有时会 返回a string而不是a boolean

因此,我的解码失败并显示:

Expected to decode Bool but found a string/data instead.

该字符串只能等于"parent",我希望它等于false

我也可以将结构更改为var manage_stock: String?是否可以简化从API导入JSON数据的过程。但是,当然,如果我更改了此设置,我的错误将变为:

Expected to decode String but found a number instead.

有没有一种简单的方法来处理这种突变,或者我需要失去所有Codable带来表的自动化并实现我自己的自动化init(decoder: Decoder)

干杯


阅读 344

收藏
2020-07-07

共1个答案

一尘不染

由于您无法始终控制要使用的API,因此这是一种Codable通过重写直接解决此问题的简单方法init(from:)

struct Product : Decodable {
    // Properties in Swift are camelCased. You can provide the key separately from the property.
    var manageStock: Bool?

    private enum CodingKeys : String, CodingKey {
        case manageStock = "manage_stock"
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        do {
            self.manageStock = try container.decodeIfPresent(Bool.self, forKey: .manageStock)
        } catch DecodingError.typeMismatch {
            // There was something for the "manage_stock" key, but it wasn't a boolean value. Try a string.
            if let string = try container.decodeIfPresent(String.self, forKey: .manageStock) {
                // Can check for "parent" specifically if you want.
                self.manageStock = false
            }
        }
    }
}

有关更多信息,请参见编码和解码自定义类型

2020-07-07