0

我想像这样发送空字典

“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)
} 
4

2 回答 2

2

该错误是由于在您的字典中有 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"}

于 2019-03-11T11:14:28.067 回答
1

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

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

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

  2. 如果无法解码,则将visitorAttrs的值设置为空字典

let visitorAttrs = try? container.decode(Dictionary<String:Any>.self, forKey: .visitorAttrs)
self.visitorAttrs = visitorAttrs ?? [:]
于 2019-03-11T11:23:09.557 回答