允许JSONDecoder()接受空数组作为空字典

问题描述 投票:1回答:3

给出此结构:

public struct Error: Codable {
    public let code: String
    public let message: String
    public let params: [String: String]?
}

以及此JSON:

[
  {
    "message" : "The requested user could not be found.",
    "params" : [],
    "code" : "requested_user_not_found"
  }
]

是否有一种方法可以在Swift中使用JSONDecoder()类对其进行解码? params键应该是字典,但是由于产生此JSON的外部API的实现方式(在PHP中),因此空字典在JSON中呈现为空数组。

目前,尝试将提供的JSON解码为提供的结构的实例会导致引发错误。

ios json swift
3个回答
1
投票

您可以检查键的值是否可解码,如果不能,则仅返回一个空数组。代码看起来像这样:

if let paramsArray = try? values.decode([String: String].self, forKey: .params) {
    params = paramsArray
} else {
    params = []
}

1
投票

尝试下面的代码段,在这里您将尝试将参数解码为字典。如果失败,我们将为其分配一个空字典。

public struct Error: Codable {
    public let code: String
    public let message: String
    public let params: [String:String]

    public init(from decoder: Decoder) throws {
        let keyedContainer = try decoder.container(keyedBy: CodingKeys.self)

        self.code = try keyedContainer.decode(String.self, forKey: .code)
        self.message = try keyedContainer.decode(String.self, forKey: .message)
        if let params = try? keyedContainer.decodeIfPresent([String: String].self, forKey: .params) {
            self.params = params
        } else {
            self.params = [:]
        }
    }
}

希望这会有所帮助。


0
投票

使用您自己的init(from:),您首先尝试在其中解码为词典,如果失败,则将其设置为空词典。据我了解,params是字典或空数组,因此我将其设为非可选

struct ErrorInfo:可编码{公开让步代码:字符串公共公开消息:字符串公共让参数:[String:String]

init(from decoder: Decoder) throws {
    var container = try decoder.container(keyedBy: CodingKeys.self)
    code = try container.decode(String.self, forKey: .code)
    message =  try container.decode(String.self, forKey: .message)
    do {
        params = try container.decode([String: String].self, forKey: .params) 
    } catch {
        params = [:]
    }
}

}请注意,由于Error是内置类型,因此我重命名了该结构,对于自定义类型,应避免使用此类名称。

© www.soinside.com 2019 - 2024. All rights reserved.