如何从JSON文件中仅解析当前用户使用的单语言内容?
问题描述
我有如下JSON文件:
[ { "id": 123, "textEN": "something", "textDE": "irgendwas" }, ... ]
同时我的开发环境中有如下结构体:
struct Something: Codable, Identifiable, Hashable { var id: Int var text: String }
我可通过Locale.current.language.languageCode?.identifier获取用户设置的语言,请问仅解析用户当前使用语言的最优或最简方案是什么?我考虑过以下方案但遇到问题:
- 解析所有语言后在视图中用switch判断,虽可行但代码质量极差;
- 解析所有语言后在视图前增加逻辑层,由管理器或视图模型移除非用户语言的翻译,虽可行但是否有更优方案?
- 仅解析并存储当前用户使用的语言内容,这应为最优方案,但未能实现:尝试用拼接字符串("text"+语言代码)作为CodingKey,但无法将变量用作CodingKey。
最优解决方案:动态字段解码
核心思路是自定义解码逻辑,在解码阶段直接根据当前语言读取对应字段,无需解析冗余数据。具体实现如下:
- 自定义动态CodingKey类型
创建支持动态字符串key的CodingKey,解决变量无法直接作为CodingKey的问题:
struct DynamicCodingKey: CodingKey { var stringValue: String init?(stringValue: String) { self.stringValue = stringValue } var intValue: Int? init?(intValue: Int) { return nil } }
- 修改
Something结构体的解码实现
手动实现init(from decoder:)方法,在解码时动态匹配当前语言对应的字段:
struct Something: Codable, Identifiable, Hashable { var id: Int var text: String init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: DynamicCodingKey.self) // 解码固定id字段 id = try container.decode(Int.self, forKey: DynamicCodingKey(stringValue: "id")!) // 获取当前语言代码,默认用"EN"兜底 let langCode = Locale.current.language.languageCode?.identifier.uppercased() ?? "EN" let targetTextKey = "text\(langCode)" // 解码对应语言的文本字段 text = try container.decode(String.self, forKey: DynamicCodingKey(stringValue: targetTextKey)!) } }
- 解码使用示例
直接用标准JSONDecoder解码即可,只会解析id和当前语言对应的textXX字段:
let jsonData = """ [ {"id": 123, "textEN": "something", "textDE": "irgendwas"}, {"id": 456, "textEN": "hello", "textDE": "hallo"} ] """.data(using: .utf8)! do { let somethings = try JSONDecoder().decode([Something].self, from: jsonData) print(somethings) } catch { print("解码失败:\(error)") }
方案优势
- 解码阶段只读取需要的字段,无冗余数据处理,性能最优
- 逻辑集中在结构体内部,无需额外管理类或视图模型层
- 自动适配系统语言,无需在视图层做分支判断
内容的提问来源于stack exchange,提问作者olvrwn
相关产品推荐
相关产品推荐

