我正在从 API 检索 JSON,并且想为我使用的每个端点创建一个模型。
\n\n所有端点都使用以下格式:
\n\n{\n "id": "xxxxxx",\n "result": {\xe2\x80\xa6},\n "error": null\n}\nRun Code Online (Sandbox Code Playgroud)\n\n关键是:
\n\nid始终是一个字符串error可以为空或包含键的对象result可以为null;一个对象或一个数组。我遇到的问题是,在端点之一上,结果是数组的数组:
\n\n{\n "id": "xxxxxx",\n "result": [\n [\n "client_id",\n "name",\n 50,\n "status"\n ]\n ],\n "error": null\n}\nRun Code Online (Sandbox Code Playgroud)\n\n正如您所看到的,我有数组的数组,其中值可以是字符串或整数。
\n\n如何使用 Decodable 协议对其进行解码,然后根据其原始值将这些解码值用作 String 或 Int ?
\n最近我加入Codable了一个项目并JSON从符合Encodable我的类型中获取一个对象,我想出了这个扩展,
extension Encodable {
/// Converting object to postable JSON
func toJSON(_ encoder: JSONEncoder = JSONEncoder()) -> [String: Any] {
guard let data = try? encoder.encode(self),
let object = try? JSONSerialization.jsonObject(with: data, options: .allowFragments),
let json = object as? [String: Any] else { return [:] }
return json
}
}
Run Code Online (Sandbox Code Playgroud)
这很有效,但有没有更好的方法来实现同样的目标?
我正在尝试实现一个与如何Codable使用CodingKeys枚举具有类似功能的协议。
使用Codableand CodingKeys,如果您没有在CodingKeys枚举中为Codable对象的每个属性实现 case ,则会导致编译器错误,指出该对象不符合协议。
我查看了文档,唯一能找到的与Codable( Encodableand Decodable) 协议相关的是实现func encode(to encoder: Encoder)和init(from decoder: Decoder)功能的要求。
我得到的最接近的是定义一个协议如下:
protocol TestProtocol {
associatedType Keys: CodingKey
}
Run Code Online (Sandbox Code Playgroud)
这要求实现者具有Keys符合的属性CodingKey,但它并不强制要求对所有属性都有一个案例。此外,您不能Keys像使用Codable.
是Codable和CodingKeys在比什么是透过API暴露了更深层次处理?
如果没有,有没有办法在CodingKeys外部实现功能Codable?
我有一个符合可解码的结构。它有 50 个 String 属性和只有一个 Bool。该 bool 来自服务器,如字符串“false”/“true”或有时像整数 0/1,因此无法从框中解码。我怎样才能让它解码但不写大量的所有 50 个字符串属性的手动解码?也许以某种方式覆盖 Bool 的 decodeIfPresent,但我无法让它工作。我如何才能避免通过手动解码所有内容和所有内容并仅处理那个 Bool 来创建 init?如果可能,没有计算属性。
struct Response: Decodable {
var s1: String
var s2: String
var s3: String
//...........
var s50: String
var b1: Bool
var b2: Bool
}
Run Code Online (Sandbox Code Playgroud)
这是 json 示例:
{
"s1":"string"
"s2":"string"
"s3":"string"
//..........
"s50":"string"
"b1":"true"
"b2":"0"
}
Run Code Online (Sandbox Code Playgroud)
试过这个但不起作用(((
extension KeyedDecodingContainer { //Doesn't work, no execution
func decodeIfPresent(_ type: Bool.Type, forKey key: K) throws -> Bool {
return try! self.decodeIfPresent(Bool.self, forKey: key)
}
func decodeIfPresent(_ …Run Code Online (Sandbox Code Playgroud)