【问题标题】:Decode Custom Json with Decodable使用 Decodable 解码自定义 Json
【发布时间】:2018-01-31 11:34:07
【问题描述】:

我有这个 Json:

{   "first": {
    "house": [
      "small"
    ]

  },   "second": {
    "house": [
      "small"
    ]   },   "third": {
    "car": [
      "fast",
      "economic"
    ]   },   "fourth": {
    "car": [
      "fast",
      "economic"
    ]   },   "fifth": {
    "car": [
      "fast",
      "economic"
    ],
    "ice": [
      "round",
      "tasty"
    ],
    "tree": [
      "big",
      "small"
    ]   } }

我尝试使用 Decodable 设置结构,但无法正常工作:

struct secondLayer: Codable {
    let exchange:  [String: [String]]
}

struct decodeJson: Codable {
    let symbol: [String: [secondLayer]]

    static func decode(jsonString: String) -    [decodeJson] {
        var output = [decodeJson]()
        let decode = JSONDecoder()
        do {
            let json = jsonString.data(using: .utf8)
            output = try! decode.decode([decodeJson].self, from: json!)
        } catch {
            print(error.localizedDescription)
        }
        return output
    }
}

我收到此错误:

Fatal error: 'try!' expression unexpectedly raised an error:
Swift.DecodingError.typeMismatch(Swift.Array<Any>,
Swift.DecodingError.Context(codingPath: [], debugDescription:
"Expected to decode Array<Any    but found a dictionary instead.",
underlyingError: nil)): file
/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.74.1/src/swift/stdlib/public/core/ErrorType.swift,
line 181

我尝试了一些修改,但无法正常工作。

【问题讨论】:

标签: json swift decodable


【解决方案1】:

错误信息

“应解码Array&lt;Any&gt;,但找到了字典。”

很清楚。你想解码一个数组([decodeJson]),但根对象是一个字典(以{开头)

您的代码无论如何都无法工作。 JSON 中没有键 exchangesymbol

基本上有两种方法可以解码 JSON:

如果所有键都是动态,则无法将 JSON 解码为结构。您必须将其解码为[String:[String:[String]]]。在这种情况下,Codable 与传统的JSONSerialization 相比没有任何优势。

struct DecodeJson: Codable {

    static func decode(jsonString: String) -> [String:[String:[String]]] {
        var output = [String:[String:[String]]]()
        let decoder = JSONDecoder()
        do {
            let json = Data(jsonString.utf8)
            output = try decoder.decode([String:[String:[String]]].self, from: json)
            print(output)
        } catch {
            print(error.localizedDescription)
        }
        return output
    }
}

或者如果序号键firstsecond 等是静态使用伞形结构

struct Root : Codable {

    let first : [String:[String]]
    let second : [String:[String]]
    let third : [String:[String]]
    let fourth : [String:[String]]
    let fifth : [String:[String]]
}


struct DecodeJson {

    static func decode(jsonString: String) -> Root? {

        let decoder = JSONDecoder()
        do {
            let json = Data(jsonString.utf8)
            let output = try decoder.decode(Root.self, from: json)
            return output
        } catch {
            print(error.localizedDescription)
            return nil
        }
    }
} 

当然,您可以将housecar 等解码为结构体,但这需要为每个结构体自定义初始化程序,因为您必须使用unkeyedContainer 手动解码单个数组

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    • 1970-01-01
    • 2019-07-24
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    相关资源
    最近更新 更多