如何在符合Codable协议的结构体中将[String: Any]用作属性?

11

我有一个符合Codable协议的结构体。我有一个类型为[String: Any]?的属性。但是Codable不允许我使用它,报错:

does not conform to protocol 'Decodable'


4
如果你想符合Codable协议,就不能在你的结构体中有Any类型。 - Joakim Danielson
你能提供更多关于你想用JSON做什么的信息吗?有不同的方法可以实现,每种方法都有其优缺点。 - rpecka
我有一个如下所述的结构体。 struct A: Codable { let a: Int let b: [String: Any] } 但是它会抛出一个错误。就像我在问题中所说的那样。 - Sarath Kumar Rajendran
请使用与您的意思相匹配的适当类型替换[String: Any][String:Any]表示“将字符串映射到可能存在的任何类型。”不可能将其转换为JSON(如果值是CBPeripheral,您会怎么做?)因此,请重新设计您的结构以使用实际意义的类型。(如果您不确定自己的意思是什么,那将是一个很好的StackOverflow问题。) - Rob Napier
是的,我对数据不确定。我唯一知道的是它将是一个字典(JSON)。 - Sarath Kumar Rajendran
1个回答

12

如果必须转换Data[String: Any]之间的格式,请使用旧的JSONSerialization类。但请注意,Data是可编码的。您也可以使用另一种格式,比如String。请注意,Swift是强类型的,因此通常优先使用带有关联值的枚举而不是使用Any。如果意图实际上是写入服务器而不是本地存储,则还可以考虑完全忘记Codable,直接使用JSONSerialization。

例子:

import UIKit
import PlaygroundSupport

struct A: Codable {
    let a: Int
    let b: [String: Any]

    enum CodingKeys: String, CodingKey {
        case a
        case b
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        a = try values.decode(Int.self, forKey: .a)
        let data = try values.decode(Data.self, forKey: .b)
        b = try JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(a, forKey: .a)
        let data = try JSONSerialization.data(withJSONObject: b, options: [])
        try container.encode(data, forKey: .b)
    }
}

3
很遗憾,这行代码无法解析:values.decode(Data.self, forKey: .b) - SoftDesigner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接