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
相关产品推荐
相关产品推荐

