I am trying to load an array of JSON
dictionaries into an object with swift using Alamofire
and SwiftyJSON
, but when the data is downloaded, I get the error:
keyNotFound(CodingKeys(stringValue: "inProrgresss", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"inProrgresss\", intValue: nil) (\"inProrgresss\").", underlyingError: nil)).
The localised description just says that the data is missing. My JSON is here and my code is like this:
struct CompData: Codable {
let inProrgresss: [[String: String]]
let past: [[String: String]]
let upcoming: [[String: String]]
}
func getData(url: URLConvertible) {
SVProgressHUD.show()
Alamofire.request(url).responseJSON { (dataResponse) in
if dataResponse.result.value != nil {
SVProgressHUD.dismiss()
let JSONVar = JSON(dataResponse.result.value)
let data = Data(dataResponse.data!)
print(data)
let decoder = JSONDecoder()
do {
let newData = try decoder.decode(CompData.self, from: data)
print("NEWDATA \(newData)")
} catch {
print(error)
}
print(JSONVar)
}
}
}
I am quite new to converting JSON into datatypes, and I couldn't find anything on here that helps.
Please read the JSON. There is no key inProrgresss
.
And create a struct for the dictionaries, it's pretty straightforward
struct CompData: Decodable {
let inProgress: [Location]?
let past: [Location]
let upcoming: [Location]
}
struct Location : Decodable {
let city, countryCode, name, date, country, id : String
}
And declare inProgress
as optional because the array is empty.
Edit:
There is a lot of redundant code in getData
. This is more efficient. convertFromSnakeCase
does what it says.
func getData(url: URLConvertible) {
SVProgressHUD.show()
Alamofire.request(url).responseData { (response) in
SVProgressHUD.dismiss()
switch response.result {
case .success(let data):
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
do {
let result = try decoder.decode(CompData.self, from: data)
print("NEWDATA \(result)")
} catch {
print(error)
}
case .failure(let error): print(error)
}
}
}