【问题标题】:IOS Swift -Unable to decode all keys from json responseIOS Swift - 无法从 json 响应中解码所有键
【发布时间】:2021-03-18 05:29:45
【问题描述】:

我是 Swift 新手,我正在尝试解析从我的服务器收到的 json 响应。我无法正确解码服务器响应。请注意,我想更改某些键的名称。正是这些键以 nil 值结束。

这是实际的服务器响应:

{
"endpoint":"14.33.21.73:53830",
"dns":"1.1.1.2",
"allowed_ips":"192.168.1.3/32",
"keep_alive":0,
"public_key":"EJueD4OvxWi-EDITED-KNb61hU4akFm1cV65tNcfyGU="
}

当我解码服务器响应时

if let data = response.body {
  let decoder = JSONDecoder()
  decoder.keyDecodingStrategy = .convertFromSnakeCase
                                
  do {
    let successResponse = try decoder.decode(T.self, from: data)
    completion(.success(successResponse))
    return
 } catch { }

}

其中 T 是下面的类。请注意,我想重命名一些字段。例如服务器返回public_key,我想将其重命名为publicKey

import Foundation

class InterfaceResult: Decodable {
    var endpoint: String?
    var dns: String?
    var allowedIps: String?
    var keepAlive: Int?
    var publicKey: String?
    
    init() {
        
    }
    
    enum CodingKeys: String, CodingKey {
        case endpoint
        case dns
        case allowedIps = "allowed_ips"
        case keepAlive = "keep_alive"
        case publicKey = "public_key"
    }
    
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        endpoint = try container.decodeIfPresent(String.self, forKey: .endpoint)
        dns = try container.decodeIfPresent(String.self, forKey: .dns)
        allowedIps = try container.decodeIfPresent(String.self, forKey: .allowedIps)
        keepAlive = try container.decodeIfPresent(Int.self, forKey: .keepAlive)
        publicKey = try container.decodeIfPresent(String.self, forKey: .publicKey)
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        
        try container.encodeIfPresent(endpoint, forKey: .endpoint)
        try container.encodeIfPresent(dns, forKey: .dns)
        try container.encodeIfPresent(allowedIps, forKey: .allowedIps)
        try container.encodeIfPresent(keepAlive, forKey: .keepAlive)
        try container.encodeIfPresent(publicKey, forKey: .publicKey)
    }
}

当来自服务器的响应被解码时,我最终重命名的字段,即 public_keypublicKey 为零。

有什么想法吗?

【问题讨论】:

  • 您不能同时设置.convertFromSnakeCase 和使用CodingKeys 枚举,因为这会导致冲突。解码器将同时转换为蛇形大小写 查找带有下划线的键,例如 public_key。所以删除其中之一。此外,所有值真的可以为零吗?仅在需要时使用可选。而且您不需要任何自定义解码/编码代码。
  • 删除 keyDecodingStrategy 解决了我的问题。我对swift很陌生。谢谢乔金姆。

标签: swift


【解决方案1】:

我建议对 JSONDecoder 使用常规初始化程序,您不需要使用 . convertFromSnakeCase 足以将枚举与 CodingKeys 协议一起使用。

要使用可解码模型快速解码数据,您必须执行以下步骤:

  1. 获取端点json数据
  2. 根据这些数据创建您的模型
  3. 模型常量或变量应与您的 json 中的键相同 3.1) 如果你想使用自定义键,你可以使用 CodingKeys 协议和指定的初始化器需要 init(from decoder: Decoder) throws {}
  4. 确保您的泛型函数获得正确的模型类型
  5. 您不必从响应中获取正文,NSURLSession 已经具有从请求返回数据的内置方法

【讨论】:

    猜你喜欢
    • 2021-09-17
    • 2022-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多