字符串:任何不符合协议'可解码'

时间:2018-04-25 19:05:31

标签: swift decodable

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

这是我的代码:

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

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

但是我收到了这个错误:

输入' MyClass.myStruct'不符合协议' Decodable'

如何在没有此错误的情况下将变量声明为字典?

我真的很感谢你的帮助

2 个答案:

答案 0 :(得分:3)

您目前无法使用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(可能会在2018年WWDC上宣布,并在2018年9月/ 10月左右完成)。

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

答案 1 :(得分:3)

嗯......从技术上讲,你可以这样做,但它需要你使用第三方组件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)
}