【问题标题】:Declare empty dictionary in codable class在可编码类中声明空字典
【发布时间】:2019-08-01 16:06:36
【问题描述】:

我想发送这样的空字典

“visitor_attrs”: {}

我尝试在一个类中实现空字典。在解码器中,我收到警告:

没有“解码”候选产生预期的上下文结果类型“字典”

我该怎么做?

var data: String
var event: String
var visitorAttrs: Dictionary<String, Any>

init(data: String, event: String) {
    self.data = data
    self.event = event
    self.visitorAttrs = [:]
}

private enum CodingKeys: String, CodingKey {
    case data
    case event
    case visitorAttrs = "visitor_attrs"
}

required public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    self.data = try container.decode(String.self, forKey: .data)
    self.event = try container.decode(String.self, forKey: .event)
    self.visitorAttrs = try container.decode(Dictionary<String:Any>.self, forKey: .visitorAttrs)
}

public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(self.data, forKey: .data)
    try container.encode(self.event, forKey: .event)
    try container.encode(self.visitorAttrs, forKey: .visitorAttrs)
} 

【问题讨论】:

    标签: ios swift codable decodable encodable


    【解决方案1】:

    错误是由于字典中有 Any 作为值并且 Any 不可解码,将其替换为 String(或您拥有的任何数据类型),这应该可以工作。

    var visitorAttrs: Dictionary<String, String>
    

    修复此问题,您将获得预期的行为

    let item = Item(data: "data", event: "event") //I gave your class the name Item
    let encoder = JSONEncoder()
    
    do {
        let data = try encoder.encode(item)
        if let str = String(data: data, encoding: .utf8) {
            print(str)
        }
    } catch {
        print(error)
    }
    

    输出是

    {"event":"event","visitor_attrs":{},"data":"data"}

    【讨论】:

    • 另一个选项是在这里使用空的Codable 类型。喜欢struct Stub: Codable {}。它也可以工作,并且不需要提供不相关的类型信息,如&lt;String, String&gt;
    • @user28434 是的,但如果它有时会包含数据,则完整的用例尚不清楚。
    • 确实如此,但如果它包含数据,使用Codable 类可能会更好,只有所有字段都是Optional。我怀疑所有值都属于同一类型。
    【解决方案2】:

    我的假设是,由于您的 JSON 响应中的 visitorAttrs 为空,因此无法从中获取字典,因为没有字典。

    你有两个选择(据我所知)

    1. visitorAttrs 属性设为可选,这样,如果您没有任何东西,它仍然能够正确解码,或者,

    2. 如果解码失败,将 visitorAttrs 的值设置为空字典

    let visitorAttrs = try? container.decode(Dictionary<String:Any>.self, forKey: .visitorAttrs)
    self.visitorAttrs = visitorAttrs ?? [:]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-24
      • 1970-01-01
      • 1970-01-01
      • 2016-11-11
      • 1970-01-01
      • 1970-01-01
      • 2011-11-13
      • 1970-01-01
      相关资源
      最近更新 更多