O.
I have a JSON file in my XCode project. Lets use this as an example:
{ "shifts": [
{"name": "Mary",
"role": "Waiter"},
{"name": "Larry",
"role": "Cook"}
]
}
In my JSONManager.swift, I have something along the lines of this:
struct Shift: Codable {
let role, name: String
static let allShifts: [Shift] = Bundle.main.decode(file: "shifts.json")
}
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")
}
return loadedData
}
}
I keep hitting the fatalError("Could not decode \(file) in the project")
and I'm wondering if it's because the JSON is not formatted correctly or why it can't decode the JSON from the JSON file.
CodePudding user response:
I fixed my own mistake. I don't need the
{ "shifts": }
in my JSON
CodePudding user response:
Take a look at you JSON structure for a momement.
You have a element called shifts
, which is any array of other elements, but your code seems to trying to load a structure which only contains the child element.
Instead, you need a outer struct
which contains the child struct
, for example...
struct Shift: Codable {
let role, name: String
}
struct Shifts: Codable {
let shifts: [Shift]
}
Then you'd use the parent struct
as the initial source type when decoding the content...
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")
}
return loadedData
}
}
let shifts: Shifts = Bundle.main.decode(file: "shifts.json")
I tested this in playgrounds and it worked fine.
There might be away to decode the structure without needing the "parent" struct
, but this works for me.