Swift JSON解码器是否用默认值替换所有丢失的密钥



我想为阶段性的功能发布、季节性变化、优惠等设置一个远程配置文件,这些都不值得通过应用程序审查。

我曾经使用n分隔的文本文件,但对于多行字符串,这会变得有点尴尬。

我目前正在编写一个小的单例,从远程URL解析配置文件,而不是为此导入一些像Firebase这样臃肿的框架。

然而,我现在面临一个问题:

如果远程json包含一个在我的Codable结构中没有定义的键,那么一切都很好,我仍然会得到带有所有定义键的对象。反之亦然,如果json缺少结构中定义的键,JSONDecoder将无法解码。示例:

let testJSON = """
{"version":1,"includedB":"B","___notIncludedC":"C"}
"""
struct DefaultConfiguration : Codable {
var version = 1
var includedB = "2"
var notIncludedC = "3"
}

我可以使解码"quot;工作"quot;通过将notIncludedC定义为可选的String?,这使得解码后的结果为nil,而不是保持其预定义的默认值。

SO上的所有答案都提到为每个键定义自定义方法,但我更愿意使用";跳过未知并保持值"0";方法,因为对于大型JSON,这将带来大量开销代码。

正如评论中所描述的那样,您必须编写自己的init((,因为合成的init无法提供您需要的行为:

let testJSON = """
{"version":1,"includedB":"B","notIncludedC":"C"}
"""
struct DefaultConfiguration : Codable {
var version = 1
var includedB = "2"
var notIncludedC = "3"
enum CodingKeys: String, CodingKey {
case version
case includedB
case notIncludedC
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
version = try container.decode(Int.self, forKey: .version)
includedB = try container.decode(String.self, forKey: .includedB)
notIncludedC = try container.decodeIfPresent(String.self, forKey: .notIncludedC) ?? "3"
}
}

最新更新