Swift JSONDecoder 默认替换所有缺失的键?
Posted
技术标签:
【中文标题】Swift JSONDecoder 默认替换所有缺失的键?【英文标题】:Swift JSONDecoder replace all missing keys by default value? 【发布时间】:2022-01-05 06:32:58 【问题描述】:我想为不值得通过 App Review 的分阶段功能发布、季节性变化、优惠等设置远程配置文件。
我曾经使用\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"
我可以通过将 notIncludedC 定义为可选的 String?
来使解码“工作” - 但是这会使解码后的结果为 nil
,而不是保持其预定义的默认值。
关于 SO 的所有答案都提到为每个键定义自定义方法,但我更愿意使用“跳过未知并保留值”方法,因为对于大型 JSON,这会带来大量开销代码。
【问题讨论】:
您必须编写自己的解码初始化程序。合成的Decodable
一致性不能满足您的需求,因此您必须自己编写。无论如何,它应该不需要太多代码
将可选属性设为可选是 imo 最直接的解决方案。
【参考方案1】:
正如 cmets 中所述,您必须编写自己的 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"
【讨论】:
很糟糕,显然没有其他解决方案,感谢您抽出宝贵时间!以上是关于Swift JSONDecoder 默认替换所有缺失的键?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Swift 4 中的 JSONDecoder,缺少的键可以使用默认值而不是可选属性吗?
使用 Swift 4 中的 JSONDecoder,缺少的键可以使用默认值而不是可选属性吗?
使用 Swift 4 中的 JSONDecoder,缺少的键可以使用默认值而不是可选属性吗?