Swift 4 Codable-Bool或String值 [英] Swift 4 Codable - Bool or String values

查看:359
本文介绍了Swift 4 Codable-Bool或String值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正在寻找一些有关如何处理我最近遇到的情况的输入.

Looking for some input as to how you would handle the scenario I recently ran into.

我一直在成功使用Swift 4s Codable,但是今天发现了意外的意外.我正在使用的API表示它为密钥manage_stock返回了boolean.

I have been using Swift 4s Codable with success but today noticed a crash that I didn't expect. The API that I am working with, says it returns a boolean for the key manage_stock.

我的存根结构如下:

struct Product: Codable {
    var manage_stock: Bool?
}

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

That works fine, the problem is that the API sometimes returns a string instead of a boolean.

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

Because of this, my decode fails with:

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

该字符串仅等于"parent",我希望它等于false.

The string only ever equals "parent" and I want it to equate to false.

我也可以将结构更改为var manage_stock: String?,如果这样可以更轻松地从API中引入JSON数据.但是,当然,如果我更改此设置,我的错误将更改为:

I am also fine with changing my struct to var manage_stock: String? if that makes things easier to bring the JSON data in from the API. But of course, if I change that, my error just changes to:

Expected to decode String but found a number instead.

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

Is there a simple way to handle this mutation or will I need to lose all the automation that Codable brings to the table and implement my own init(decoder: Decoder).

欢呼

推荐答案

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

Since you can't always be in control of the APIs you're working with, here's one simple way to solve this with Codable directly, by overriding 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
            }
        }
    }
}

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

See Encoding and Decoding Custom Types for more info on this.

这篇关于Swift 4 Codable-Bool或String值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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