Swift中如何遍历嵌套JSON对象?谷歌API邮政编码获取问题
解决Google API JSON解析获取邮政编码的问题
看起来你遇到的问题主要集中在类型不匹配、不安全的数组索引访问,以及模型定义不符合Swift编码规范这几个点上。我来一步步帮你修正:
1. 核心问题分析
- 类型不匹配:你的
address_components结构体里把long_name定义成了Int,但API返回的邮政编码是字符串类型(比如"400604"),这会直接触发解码失败。 - 硬索引不可靠:直接取
address_components[0]是不安全的,API返回的地址组件顺序可能会变化,应该通过types字段精准筛选出postal_code类型的项。 - 模型命名与键映射错误:Swift结构体名应遵循大驼峰规范,且JSON的蛇形键(比如
compound_code)需要和Swift的驼峰属性正确映射,否则会出现解码匹配失败。
2. 修正后的模型定义
按照Swift编码规范和API返回结构,重新定义模型:
struct MapModel: Decodable { let results: [Result] let status: String? // 标记为可选,避免API返回缺失时解码失败 let plusCode: CompoundCode // 映射JSON蛇形键到Swift驼峰属性 enum CodingKeys: String, CodingKey { case results, status case plusCode = "plus_code" } } struct CompoundCode: Decodable { let compoundCode: String let globalCode: String enum CodingKeys: String, CodingKey { case compoundCode = "compound_code" case globalCode = "global_code" } } struct Result: Decodable { let addressComponents: [AddressComponent] enum CodingKeys: String, CodingKey { case addressComponents = "address_components" } } struct AddressComponent: Decodable { let longName: String let shortName: String let types: [String] enum CodingKeys: String, CodingKey { case longName = "long_name" case shortName = "short_name" case types } }
3. 修正后的解析函数
修改解析逻辑,通过types筛选邮政编码,代替硬索引访问:
func parseJson(json: Data) { let decoder = JSONDecoder() do { let decodedData = try decoder.decode(MapModel.self, from: json) // 精准筛选类型为postal_code的地址组件 if let postalCodeComponent = decodedData.results.first?.addressComponents.first(where: { $0.types.contains("postal_code") }) { print("邮政编码:\(postalCodeComponent.longName)") } else { print("未找到邮政编码") } } catch { print("解码错误:\(error.localizedDescription)") // 打印详细错误便于排查 print("详细错误信息:\(error)") return } }
4. 关键修正说明
- 类型修正:将
long_name从Int改为String,完全匹配API返回的字符串类型。 - 键映射处理:通过
CodingKeys完成JSON蛇形键到Swift驼峰属性的映射,符合Swift编码规范同时保证解码匹配。 - 安全筛选:用
first(where:)替代硬索引[0],确保只获取目标类型的地址组件,避免因API返回顺序变化导致的错误。 - 可选字段处理:把
status标记为可选类型,提升代码容错性,避免API返回字段缺失时解码崩溃。
内容的提问来源于stack exchange,提问作者Rajat Kotian
相关产品推荐
相关产品推荐

