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

Swift中如何将含weather数组的JSON转为Codable?

正确解析天气JSON的Swift Codable实现方案

问题根源分析

你遇到的解析失败主要有几个核心原因:

  • 误解了weather字段的结构:它是包含单个对象的数组,而非带[0]键的字典,直接用[Weather]类型即可正确映射。
  • 冗余的WeatherBase结构体完全多余,且和JSON结构不匹配,反而干扰解析逻辑。
  • description是Swift关键字,直接作为Codable属性会导致编译或解析异常,需要通过编码键做映射。
  • Rain结构体字段定义错误:当前示例JSON中无rain字段,即使后续接口返回,常见字段也是1h/3h而非umh。

修正后的完整代码

import Foundation

struct WeatherResponse: Codable {
    let coord: Coord
    let weather: [Weather]
    let base: String
    let main: Main
    let visibility: Int
    let wind: Wind
    let clouds: Clouds
    let dt: Int
    let sys: Sys
    let timezone: Int
    let id: Int
    let name: String
    let cod: Int
    // 若后续接口可能返回rain字段,按实际结构定义(可选)
    let rain: Rain?
}

struct Coord: Codable {
    let lon: Double
    let lat: Double
}

struct Weather: Codable {
    let id: Int
    let main: String
    let description: String
    let icon: String
    
    // 处理Swift关键字description的映射
    enum CodingKeys: String, CodingKey {
        case id, main, description, icon
    }
}

struct Main: Codable {
    let temp: Double
    let feelsLike: Double
    let tempMin: Double
    let tempMax: Double
    let pressure: Int
    let humidity: Int
    
    // 将JSON下划线命名转换为Swift驼峰命名(符合编码规范)
    enum CodingKeys: String, CodingKey {
        case temp
        case feelsLike = "feels_like"
        case tempMin = "temp_min"
        case tempMax = "temp_max"
        case pressure, humidity
    }
}

struct Wind: Codable {
    let speed: Double
    let deg: Int
}

// 按天气接口常见返回结构定义Rain字段
struct Rain: Codable {
    let oneHour: Double?
    
    enum CodingKeys: String, CodingKey {
        case oneHour = "1h"
    }
}

struct Clouds: Codable {
    let all: Int
}

struct Sys: Codable {
    let type: Int
    let id: Int
    let country: String
    let sunrise: Int
    let sunset: Int
}

关键修改说明

  1. 移除冗余代码:删除完全无用的WeatherBase结构体,避免逻辑混淆。
  2. 正确映射数组:weather字段直接定义为[Weather],Codable会自动解析数组内的对象,无需手动处理索引。
  3. 关键字兼容:通过CodingKeys保留description作为属性名,同时映射JSON中的同名字段,解决关键字冲突问题。
  4. 命名规范优化:将JSON的下划线命名转换为Swift风格的驼峰命名,提升代码可读性,同时通过编码键完成映射(可选但推荐)。
  5. 修正Rain结构:按照天气接口常见返回调整字段,设为可选类型,避免无rain字段时解析失败。

解析示例代码

// 假设已获取JSON对应的Data对象
func parseWeatherData(from data: Data) -> WeatherResponse? {
    do {
        let decoder = JSONDecoder()
        // 开启自动下划线转驼峰,配合Main结构体的编码键使用
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        let response = try decoder.decode(WeatherResponse.self, from: data)
        return response
    } catch {
        print("解析失败: \(error)")
        return nil
    }
}

内容的提问来源于stack exchange,提问作者Caio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:25:20