You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift解码特殊结构JSON(Photon地理API)失败,无法提取坐标与国家代码

现有代码核心错误定位
  • 根解码类型不匹配:接口返回的是包含features字段的单个JSON对象,并非数组,原代码使用[features].self作为根解码类型,从起点就无法匹配结构
  • 字段类型匹配错误:Features结构中错误将geometry、properties声明为数组类型[Geometry]、[Properties],但实际JSON中这两个字段都是单个嵌套对象,不属于数组结构
  • 异常处理缺失:全程使用try?吞掉所有网络、解码错误,无法定位具体的结构不匹配问题
  • 编码习惯问题:结构体命名小写开头,不符合Swift的类型命名规范
  • 网络请求方式问题:使用同步的Data(contentsOf:)获取数据,会阻塞当前线程,生产环境会造成UI卡顿
修正后的可运行实现

首先是匹配JSON结构的精简Codable模型,仅声明需要提取的字段即可,未声明的JSON字段会被自动忽略:

import Foundation

// 对应返回值的根JSON对象
struct PhotonResponse: Codable {
    let features: [Feature]
}

// 对应features数组中的单个对象
struct Feature: Codable {
    let geometry: Geometry
    let properties: Properties
}

// 对应geometry嵌套对象,存储坐标信息
struct Geometry: Codable {
    let coordinates: [Double]
}

// 对应properties嵌套对象,仅保留需要提取的国家代码字段
struct Properties: Codable {
    let countrycode: String
}

然后是修正后的解码逻辑,替换掉吞异常的写法,加入错误日志方便后续调试:

var parsedFeatures: [Feature] = []
let targetURLString = "https://photon.komoot.io/api/?q=Greece"

guard let targetURL = URL(string: targetURLString) else {
    return
}

do {
    let data = try Data(contentsOf: targetURL)
    let decoder = JSONDecoder()
    // 根层级解码为单个响应对象,而非数组
    let response = try decoder.decode(PhotonResponse.self, from: data)
    parsedFeatures = response.features

    // 提取目标字段示例
    for item in parsedFeatures {
        let coordinateLon = item.geometry.coordinates[0]
        let coordinateLat = item.geometry.coordinates[1]
        let code = item.properties.countrycode
        print("提取结果:经度\(coordinateLon),纬度\(coordinateLat),国家代码\(code)")
    }
} catch {
    // 直接打印具体错误,避免盲调试
    print("运行失败:\(error.localizedDescription)")
}
开发注意事项
  • 编写Codable模型时,属性的层级、类型必须和JSON结构严格对齐,不要凭主观直觉判断字段是对象还是数组
  • 不需要提取的JSON字段无需全部写入模型,Codable会自动忽略未声明的内容,精简模型可以减少维护成本
  • 调试JSON解码问题时,禁止过度使用try?吞掉所有异常,打印具体的DecodingError可以快速定位到不匹配的字段
  • 实际生产场景请将同步网络请求替换为URLSession异步请求,避免阻塞主线程

内容的提问来源于stack exchange,提问作者Márcio Silva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 15:24:03