import Foundation
struct RGBValue: Codable {
let blue, green: Double
let timestamp: String
let red: Double
}
struct RGB: Codable {
let fps: Double
let heartRate: Int
let rgbValues: [RGBValue]
static let rgbData: [RGB] = Bundle.main.decode(file: "hrv_data.json")
static let sampleData: RGB = rgbData[0]
}
extension Bundle{
func decode<T: Decodable>(file: String) -> T {
guard let url = self.url(forResource: file, withExtension: nil) else {
fatalError("Could not find (file) in the project!")
}
guard let data = try? Data(contentsOf: url) else {
fatalError("Could not load (file) in the project!")
}
let decoder = JSONDecoder()
guard let loadedData = try? decoder.decode(T.self, from: data) else {
fatalError("Could not decode (file) in the project! error : (Error.self)")
}
return loadedData
}
}
This is the entire code snippet which shows no error, but while run time it crashes "Thread 1: Fatal error: Could not decode hrv_data.json in the project! error : Error"
How to solve the issue and know the reason behind this error?
json sample:
{
"fps": 0.1548667699098587,
"heartRate": 81,
"rgbValues": [
{
"blue": 0,
"green": 0,
"timestamp": "22-04-2024 10:33:57",
"red": 0
}
]
}
2
Answers
I really appreciate Paul Hudson’s huge effort for the Swift community, but this Bundle extension he suggests to decode a JSON file is a poor advice, I’m afraid.
It’s highly recommended to catch always the comprehensive
DecodingError
, it tells you exactly what’s wrong and even where the error occurred.Replace
with
The error is clear. The root object is a dictionary (note the enclosing
{}
), it’s not an arrayTry this example code using
decode
withdo/catch
returning an optional,plus various improvements:
File
hrv_data.json
content