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

Swift中处理Strava API功率流首值为Null的JSON解码问题

解决Strava API功率数据解码时null转0的问题

问题根源是你声明的data字段为[Double]?,但JSON返回的数组中存在null值,Swift原生Double无法解析null,导致解码失败。以下是两种实用的解决办法:

方法一:自定义解码逻辑,自动将null转为0

修改Stream结构体,手动实现解码过程,把数组中的null替换成0:

struct streamsElement: Decodable {
    struct Stream: Decodable {
        let data: [Double]
        let series_type: String
        let original_size: Int
        let resolution: String
        
        enum CodingKeys: String, CodingKey {
            case data, series_type, original_size, resolution
        }
        
        init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            // 先解码成可空Double数组,兼容null
            let optionalData = try container.decode([Double?].self, forKey: .data)
            // 将所有nil替换为0,转为非空Double数组
            data = optionalData.map { $0 ?? 0 }
            
            // 解码其他字段
            series_type = try container.decode(String.self, forKey: .series_type)
            original_size = try container.decode(Int.self, forKey: .original_size)
            resolution = try container.decode(String.self, forKey: .resolution)
        }
    }
}

解码后data数组里的null会自动转为0,后续遍历逻辑无需修改。

方法二:用自定义类型包装Double,复用null处理逻辑

定义一个专门处理null转默认值的类型,可复用在其他类似场景:

// 自定义类型,解码时自动将null转为0
struct NullableDouble: Decodable {
    let value: Double
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        value = try container.decodeIfPresent(Double.self) ?? 0
    }
}

// 修改Stream结构体的data类型
struct streamsElement: Decodable {
    struct Stream: Decodable {
        let data: [NullableDouble]
        let series_type: String
        let original_size: Int
        let resolution: String
        
        // 计算属性,直接获取Double数组
        var doubleData: [Double] {
            data.map { $0.value }
        }
    }
}

// 解码后使用方式
if let wattsData = streams.watts?.doubleData {
    for watts in wattsData {
        wattsArr.append("watts: \(watts)")
    }
}

额外需求:仅跳过第一个null值

如果只想忽略数组第一个null,可在自定义解码时调整:

init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    let optionalData = try container.decode([Double?].self, forKey: .data)
    // 跳过第一个元素,剩余元素的null转为0
    let processedData = optionalData.dropFirst().map { $0 ?? 0 }
    data = processedData
    
    // 其他字段解码...
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:55:14