Swift使用Codable解析含动态Key的restcountries接口JSON方案
Swift 解析restcountries接口动态键nativeName字段方案
核心问题原因
原实现将nativeName定义为带固定deu属性的结构体,仅能匹配返回中包含deu键的场景,无法适配接口根据国家语言动态返回不同键名的结构。由于所有nativeName下动态键对应的值结构完全一致(均包含common、official两个字符串字段),直接用字符串键的字典类型承接即可实现动态适配。
修正后实现代码
1. 数据模型修正
// 国家主数据模型 struct Country: Codable { let name: Name let cca2: String let flag: String } struct Name: Codable { let common, official: String // 核心调整:动态键字段用[String: 通用值模型]字典承接,兼容任意语言代码键 let nativeName: [String: NativeLanguageEntry]? } // 通用本地语言条目模型,所有动态键对应的值均符合该结构 struct NativeLanguageEntry: Codable { let official, common: String? }
2. 解析服务修正
class ParsingService { static let shared = ParsingService() func fetchData() { guard let url = URL(string: "https://restcountries.com/v3.1/all") else { print("DEBUG: URL无效") return } let task = URLSession.shared.dataTask(with: url) { data, _, error in guard let retrievedData = data, error == nil else { print("DEBUG: 数据拉取失败: \(error?.localizedDescription ?? "未知错误")") return } guard let decodedData = self.parseJSON(inputData: retrievedData) else { print("DEBUG: 数据解析失败") return } // 测试取值示例 guard let firstCountry = decodedData.first else { return } print("国家二字码: \(firstCountry.cca2)") print("国旗标识: \(firstCountry.flag)") // 动态取值方式1:取返回的第一个本地语言条目 if let firstEntry = firstCountry.name.nativeName?.first { print("首个本地语言(代码:\(firstEntry.key))官方名:\(firstEntry.value.official ?? "无数据")") } // 动态取值方式2:按指定语言代码查询,例如查询英语条目 if let engEntry = firstCountry.name.nativeName?["eng"] { print("英语本地通用名:\(engEntry.common ?? "无数据")") } // 动态取值方式3:遍历所有本地语言条目 firstCountry.name.nativeName?.forEach { langCode, entry in print("语言代码:\(langCode),通用名:\(entry.common ?? "无数据"),官方名:\(entry.official ?? "无数据")") } DispatchQueue.main.async { // 主线程UI更新逻辑 } } task.resume() } func parseJSON(inputData: Data) -> [Country]? { let decoder = JSONDecoder() do { // 移除原代码的try?,避免吞掉解析错误,方便排查问题 let data = try decoder.decode([Country].self, from: inputData) return data } catch { print("DEBUG: 解析错误详情: \(error)") return nil } } }
关键修改点
- 移除原实现中写死
deu属性的NativeName结构体,将nativeName字段类型改为可选字典[String: NativeLanguageEntry]?,自动适配接口返回的任意动态语言键 - 修正原解析方法中
try?吞错误的问题,解析失败时输出完整错误信息,降低调试成本 - 提供三种常用动态取值逻辑,覆盖不同业务场景下的nativeName读取需求
- 修正原代码中的拼写错误(
nill改为nil),优化模型命名语义,避免歧义
内容的提问来源于stack exchange,提问作者Rauf Aliyev
相关产品推荐
相关产品推荐

