【问题标题】:Managing Dynamic Keys in response through Codable Protocol通过可编码协议管理动态密钥以响应
【发布时间】:2021-10-22 06:35:27
【问题描述】:

我需要为来自以下响应的字典的动态键创建可编码模型是我得到的响应。

{ 
"data" : [
             {
               "desc1" : null,
               "file1" : "uploads\/posts\/Aug-2021\/1629271422310452767"
             },
             {
               "desc2" : "hello",
               "file2" : "uploads\/posts\/Aug-2021\/162927142279356160WhatsApp+Image+2021-07-02+at+12.09.14+PM.jpeg"
             }
         ],
"status" : "success"
}

这个 desc1 和 file1 是动态的,直到像 file1、file2 等等,我需要有可编码的模型,因为下面是我不支持的模型。

struct ListModel: Codable {
    public var data: [data]?
}
struct data: Codable {
   let file : String?
   let desc : String?
}

可编码协议对此的任何支持。提前致谢。

【问题讨论】:

  • 我建议您更改您的 api 以始终返回“desc”和“file”
  • 我也提出了同样的建议,但这会导致一些实施的后端出现一些问题。
  • 这就是为什么需要管理这个。
  • 你需要一个自定义初始化器
  • 自定义初始化程序,嗯,你能建议我这样做的方式吗?

标签: ios swift swift3 codable


【解决方案1】:

您需要一个自定义初始化程序。当然,这只有在您的 json 始终按照描述的格式格式化时才有效:

struct File {
    var file: String? = ""
    var desc: String? = ""
}

struct Response {
    let files: [File]
    let status: String
    enum CodingKeys: String, CodingKey {
        case files = "data", status
    }
}

extension Response: Decodable {
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.status = try container.decode(String.self, forKey: .status)
        let elements = try container.decode([[String: String?]].self, forKey: .files)
        self.files = elements.reduce(into: []) {
            var file = File()
            for (key, value) in $1 {
                if key.hasPrefix("file") {
                    file.file = value
                } else if key.hasPrefix("desc") {
                    file.desc = value
                }
            }
            $0.append(file)
        }
    }
}

游乐场测试:

let json = """
{
    "data" : [
                 {
                   "desc1" : null,
                   "file1" : "uploads/posts/Aug-2021/1629271422310452767"
                 },
                 {
                   "desc2" : "hello",
                   "file2" : "uploads/posts/Aug-2021/162927142279356160WhatsApp+Image+2021-07-02+at+12.09.14+PM.jpeg"
                 }
             ],
    "status" : "success"
}
"""

do {
    let response = try JSONDecoder().decode(Response.self, from: Data(json.utf8))
    print(response)
} catch {
    print(error)
}

这将打印:

响应(文件:[文件(文件:可选(“上传/帖子/Aug-2021/1629271422310452767”),描述:无),文件(文件:可选(“上传/帖子/Aug-2021/162927142279356160WhatsApp+图片+2021-07-02+at+12.09.14+PM.jpeg"), desc: Optional("hello"))], status: "success")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-29
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多