swift 4 Codable-如果有字符串或字典,如何解码? [英] swift 4 Codable - how to decode if there is string or dictionary?

查看:87
本文介绍了swift 4 Codable-如果有字符串或字典,如何解码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的结构:

struct OrderLine: Codable{
    let absUrl: String?
    let restApiUrl : String?
    let description : String?
    let quantity : Int?
    let subscription: Subs?
    let total: Double?
 }

struct Subs: Codable{
    let quantity: Int?
    let name: String?
}

和一些 OrderLine 在服务器响应中

"subscription": {
   "quantity": 6,
   "name": "3 Months"
},

但有时它具有 String 类型:

"subscription": "",

没有 subscription ,一切正常,但出现错误

without subscription everytthing works fine, but with I've got an error

CodingKeys(stringValue: "subscription", intValue: nil)], 
   debugDescription: "Expected to decode Dictionary<String, Any> 
   but found a string/data instead.", underlyingError: nil)

所以我的问题是-如何解码或解码值为" String?,或解码为 Subs?而没有任何错误?p.s.如果我仅像 String?那样解码它,则出现错误 debugDescription:预期对String进行解码,但找到了字典.",底层错误:nil)

so my question is - how can I decode or to String? with value "", or to Subs? without any error? p.s. if I decode it like String? only, then have error debugDescription: "Expected to decode String but found a dictionary instead.", underlyingError: nil)

推荐答案

您只需要自己实现 init(from:)并尝试解码 subscription 的值键既作为表示 Subs Dictionary ,又作为 String 的键.

You simply need to implement init(from:) yourself and try decoding the value for the subscription key both as a Dictionary representing Subs and as a String.

struct OrderLine: Codable {
    let absUrl: String?
    let restApiUrl : String?
    let description : String?
    let quantity : Int?
    let subscription: Subs?
    let total: Double?

    private enum CodingKeys: String, CodingKey {
        case absUrl, restApiUrl, description, quantity, subscription, total
    }

    init(from decoder:Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.absUrl = try container.decodeIfPresent(String.self, forKey: .absUrl)
        self.restApiUrl = try container.decodeIfPresent(String.self, forKey: .restApiUrl)
        self.description = try container.decodeIfPresent(String.self, forKey: .description)
        self.quantity = try container.decodeIfPresent(Int.self, forKey: .quantity)
        self.total = try container.decodeIfPresent(Double.self, forKey: .total)
        if (try? container.decodeIfPresent(String.self, forKey: .subscription)) == nil {
            self.subscription = try container.decodeIfPresent(Subs.self, forKey: .subscription)
        } else {
            self.subscription = nil
        }
    }
}

这篇关于swift 4 Codable-如果有字符串或字典,如何解码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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