Codable/Decodable 应该用字符串解码数组

Jan*_*Jan 5 swift swift4 codable decodable

为什么名称 Array 没有解码?

为 Playground 做好准备,简单地将其粘贴到您的 Playground 中

import Foundation

struct Country : Decodable {

    enum CodingKeys : String, CodingKey {
        case names
    }

    var names : [String]?
}

extension Country {
    public init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        names = try values.decode([String]?.self, forKey: .names)!
    }
}

let json = """
 [{
    "names":
      [
       "Andorre",
       "Andorra",
       "????"
      ]
 },{
    "names":
      [
       "United Arab Emirates",
       "Vereinigte Arabische Emirate",
       "Émirats Arabes Unis",
       "Emiratos Árabes Unidos",
       "????????",
       "Verenigde Arabische Emiraten"
      ]
  }]
""".data(using: .utf8)!

let decoder = JSONDecoder()
do {
    let countries = try decoder.decode([Country].self, from: json)
    countries.forEach { print($0) }
} catch {
    print("error")
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 2

您已定义names为 的可选属性Country。如果您的意图是该密钥可能不存在于 JSON 中,则使用decodeIfPresent

extension Country {
    public init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        names = try values.decodeIfPresent([String].self, forKey: .names)
    }
}
Run Code Online (Sandbox Code Playgroud)

nil如果容器没有与键关联的值,或者值为 null,则此方法返回。

但实际上您可以省略自定义init(from decoder: Decoder) 实现(和enum CodingKeys),因为这是默认行为并且将自动合成。

备注:隐式变量error可以在任何子句中定义catch,因此

} catch {
    print(error.localizedDescription)
}
Run Code Online (Sandbox Code Playgroud)

可以比 a 提供更多信息print("error")(尽管不是在这种特殊情况下)。