首页 文章

致命错误:Dictionary <String,Any>不符合Decodable,因为Any不符合Decodable

提问于
浏览
5

我正在尝试使用swift 4来解析本地json文件:

{
    "success": true,
    "lastId": null,
    "hasMore": false,
    "foundEndpoint": "https://endpoint",
    "error": null
}

这是我正在使用的功能:

func loadLocalJSON() {

        if let path = Bundle.main.path(forResource: "localJSON", ofType: "json") {
            let url = URL(fileURLWithPath: path)

            do {
                let data  = try Data(contentsOf: url)
                let colors = try JSONDecoder().decode([String: Any].self, from: data)
                print(colors)
            }
            catch { print("Local JSON not loaded")}
        }
    }
}

但我一直收到错误:

致命错误:Dictionary不符合Decodable,因为Any不符合Decodable .

我尝试在此stackoverflow页面上使用"AnyDecodable"方法:How to decode a property with type of JSON dictionary in Swift 4 decodable protocol但它在使用时跳转到'catch'语句: catch { print("Local JSON not loaded") . 有谁知道如何在Swift 4中解析这个JSON数据?

2 回答

  • 3

    也许你误解 Codable 是如何工作的 . 它基于具体类型 . Any 不受支持 .

    在您的情况下,您可以创建一个类似的结构

    struct Something: Decodable {
        let success : Bool
        let lastId : Int?
        let hasMore: Bool
        let foundEndpoint: URL
        let error: String?
    }
    

    并解码JSON

    func loadLocalJSON() {
        let url = Bundle.main.url(forResource: "localJSON", withExtension: "json")!
        let data  = try! Data(contentsOf: url)
        let colors = try! JSONDecoder().decode(Something.self, from: data)
        print(colors)
    }
    

    任何崩溃都会显示设计错误 . 在主包中的文件中使用 null 的意义是另一个问题 .

  • 3

    我使用quicktype生成Codables和编组代码:

    https://app.quicktype.io?gist=02c8b82add3ced7bb419f01d3a94019f&l=swift

    我根据您的样本数据给出了一系列样本:

    [
      {
        "success": true,
        "lastId": null,
        "hasMore": false,
        "foundEndpoint": "https://endpoint",
        "error": null
      },
      {
        "success": true,
        "lastId": 123,
        "hasMore": false,
        "foundEndpoint": "https://endpoint",
        "error": "some error"
      }
    ]
    

    这告诉quicktype假设您的第一个样本中的 null 值有时是 IntString - 如果它们不是可能的类型,您可以更改它们 . 生成的Codable是:

    struct Local: Codable {
        let success: Bool
        let lastID: Int?
        let hasMore: Bool
        let foundEndpoint: String
        let error: String?
    
        enum CodingKeys: String, CodingKey {
            case success
            case lastID = "lastId"
            case hasMore, foundEndpoint, error
        }
    }
    

相关问题