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

Swift中JSON的Double值解码为CGFloat失败的解决方法

解决Swift解码JSON中数值/字符串混合字段的问题

问题分析

核心问题是JSON数据集中的scaleFactor字段类型不一致:部分条目是数值类型(如1.1),但空字段或异常值被存储为字符串类型(如""),而Swift的JSONDecoder无法自动处理这种类型混合的解码场景,直接用CGFloat.self解码会触发崩溃。

解决方案

方案1:修改JSON数据集(推荐,逻辑更简洁)

直接统一JSON中scaleFactor字段的类型:

  • 将所有空值替换为null或默认数值(如0.5)
  • 确保所有数值类型的scaleFactor保持为纯数值格式(不要用引号包裹)

修改后,可直接恢复原解码代码:

scaleFactor = try container.decode(CGFloat.self, forKey: .scaleFactor)

方案2:在Swift代码中兼容解析

如果无法修改数据集,可自定义解码逻辑,同时处理数值和字符串两种输入类型:

方法A:直接在init(from:)中处理

替换Monster结构体init(from decoder:)中注释的scaleFactor相关代码为:

// 处理scaleFactor的兼容解码
do {
    // 优先尝试解码为Double(JSON数值类型)
    let doubleScale = try container.decode(Double.self, forKey: .scaleFactor)
    scaleFactor = CGFloat(doubleScale)
} catch {
    // 解码失败,尝试解码为String类型
    let stringScale = try container.decode(String.self, forKey: .scaleFactor)
    // 尝试将字符串转为Double,失败则用默认值0.5
    scaleFactor = CGFloat(Double(stringScale) ?? 0.5)
}

方法B:自定义可解码包装类型(更优雅,可复用)

创建通用包装类型,统一处理数值与字符串的兼容解析:

struct FlexibleCGFloat: Codable {
    let value: CGFloat
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        
        // 优先尝试解码为数值类型
        if let doubleValue = try? container.decode(Double.self) {
            value = CGFloat(doubleValue)
        } 
        // 尝试解码为字符串并转换
        else if let stringValue = try? container.decode(String.self) {
            value = CGFloat(Double(stringValue) ?? 0.5)
        } 
        // 都失败则使用默认值(或抛出错误)
        else {
            value = 0.5
            // 若需严格校验,可抛出错误:
            // throw DecodingError.dataCorruptedError(in: container, debugDescription: "scaleFactor格式无效,需为数值或可转换的字符串")
        }
    }
}

随后在Monster的init(from:)中使用该包装类型:

let flexibleScale = try container.decode(FlexibleCGFloat.self, forKey: .scaleFactor)
scaleFactor = flexibleScale.value

额外检查

确认CodingKeys枚举已包含scaleFactor,从提供的代码看该字段已存在,无需修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 16:25:25