字符串字典:任何不符合协议“可解码”[重复]

Posted

技术标签:

【中文标题】字符串字典:任何不符合协议“可解码”[重复]【英文标题】:Dictionary of String:Any does not conform to protocol 'Decodable' [duplicate] 【发布时间】:2018-10-06 08:48:19 【问题描述】:

我正在尝试实现 Decodable 来解析 json 请求,但 json 请求在对象内部有一个字典。

这是我的代码:

    struct myStruct : Decodable 
        let content: [String: Any]


        enum CodingKeys: String, CodingKey 
            case content = "content"

但我收到此错误:

类型“MyClass.myStruct”不符合协议“Decodable”

如何将变量声明为字典而不出现此错误?

非常感谢您的帮助

【问题讨论】:

字典是不可解码的。也许发布 JSON。 Any 不符合 Decodable,所以 Dictionary<String:Any> 也不符合。如果您确实需要存储具有完全动态键/值的字典,因此不能使用具体类型而不是Any,那么您需要坚持使用JSONSerialization。如果您确实知道所有键及其值的预期类型,则将值存储为具有具体类型的类的属性。 @user2924482 试试我的answer below。两全其美:Decodable + [String:Any] 【参考方案1】:

嗯...从技术上讲,您可以这样做,但它需要您使用第三方组件 SwiftyJSON 来表示字典。

另外,我假设您这样做是因为 content 可能有非规范化数据,并且您有意将其视为字典。

在这种情况下,请继续:

import SwiftyJSON

struct MyStruct : Decodable 
    //... your other Decodable objects like
    var name: String

    //the [String:Any] object
    var content: JSON

这里,JSON 是 SwiftyJSON 对象,它将代表您的字典。事实上它也可以代表一个数组。


工作示例:

let jsonData = """

  "name": "Swifty",
  "content": 
    "id": 1,
    "color": "blue",
    "status": true,
    "details": 
        "array" : [1,2,3],
        "color" : "red"
    
  

""".data(using: .utf8)!

do 
    let test = try JSONDecoder().decode(MyStruct.self,
                                        from: jsonData)
    print(test)

catch 
    print(error)

【讨论】:

【参考方案2】:

您目前无法使用 Swift 编码框架解码 [String: Any]。如果您需要解码[String: Any],则需要使用较低级别的反序列化策略并“手动”解码。例如,如果您的输入是 JSON,您可以使用 Foundation 的 JSONSerialization 或像 SwiftyJSON 这样的第三方库。

在 Swift Evolution 上已经讨论过这个问题:“Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4”。 Apple 的主要 Coding/Codable 程序员 Itai Ferber 已参与讨论并有兴趣提供解决方案,但 it is unlikely to happen for Swift 5(可能会在 WWDC 2018 上宣布并在 2018 年 9 月/10 月左右最终确定)。

您可以将JSONDecoder(它是开源的)的实现复制到您的项目中并对其进行修改以添加获得未评估的[String: Any] 的功能。 Itai 在我上面链接的线程中讨论了所需的修改。

【讨论】:

以上是关于字符串字典:任何不符合协议“可解码”[重复]的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - 类型“服务”不符合协议“可解码”

不符合协议 Decodabel 和 Encodable

尝试符合可等式泛型 Set 时,类型“任何”不符合协议“等式”

给定一个字符串列表,如果任何值等于列表中的值,我想将字典的值添加到新字典中[重复]

在协议缓冲区中定义字典

类型“字符串”不符合协议“NilLiteralConvertiblle”