When trying to use the Strava API with wattages per second I keep running into the problem of the first value always being null instead of a number.
struct streamsElement: Decodable {
struct Stream: Decodable {
let data: [Double]?
let series_type: String
let original_size: Int
let resolution: String
}
//decoding
if let wattsData = streams.watts?.data {
for watts in wattsData {
wattsArr.append("watts: \(watts)" )
}
}
"watts":{"data":[
null,
144,
98,
95, etc.
This works fine for all the other streams.
Error
Error decoding JSON data: valueNotFound(Swift.Double, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "watts", intValue: nil), CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "Expected Double but found null value instead.", underlyingError: nil))
How can i turn this Null value into a zero so I don't get a JSON decoding error?
I tried to skip the first value in the decoding but this did not work.
CodePudding user response:
You don´t have to turn the null
JSON value into a 0 just to prevent the crash. Change the the type of the array to an optional and you are good to go. E.g.:
struct Stream: Decodable {
let data: [Double?] // add a ? if the array itself is optional too
let series_type: String
let original_size: Int
let resolution: String
}
I don´t know why and where you do what you described as decoding. But if you want your data
Double´s to be nonoptional you could do something like this in a custom decoder:
struct streamsElement: Decodable {
struct Stream: Decodable {
let data: [Double]
enum CodingKeys: CodingKey{
case data
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
// decode the data property to the array of optionals
let data = try container.decode([Double?].self, forKey: .data)
// replace nil values with 0
self.data = data.map{$0 ?? 0}
}
}
var watts: Stream
}
I´ve implemented only the problematic property. Of course you would need to expand this to the others.