I have been wrestling with this for a while. I am trying to parse a JSON Api into a UITableview. The url is Formula One API . I am using Codable rather than third party pods. Thought this might cut down on the amount of code. Although, as the API is not that straight forward it is hard to extract what I want. Basically, I want to list the current standing for drivers for a given year. In url and code I have given I have chosen 1999 as an example. I have been researching on Stackoverflow but each solution is very specific to a particular problem and I can't seem to relate to my issue. Below is the code I have.
struct MRData: Codable {
let xmlns: String?
let series: String?
let url: String?
let limit, offset, total: String?
let standingsTable: StandingsTable
enum CodingKeys: String, CodingKey {
case xmlns, series, url, limit, offset, total
case standingsTable = "StandingsTable"
}
}
struct StandingsTable: Codable {
let season: String?
let standingsLists: [StandingsList]
enum CodingKeys: String, CodingKey {
case season
case standingsLists = "StandingsLists"
}
}
struct StandingsList: Codable {
let season, round: String?
let driverStandings: [DriverStanding]
enum CodingKeys: String, CodingKey {
case season, round
case driverStandings = "DriverStandings"
}
}
struct DriverStanding: Codable {
let position, positionText, points, wins: String?
let driver: Driver
let constructors: [Constructor]
enum CodingKeys: String, CodingKey {
case position, positionText, points, wins
case driver = "Driver"
case constructors = "Constructors"
}
}
struct Constructor: Codable {
let constructorId: String?
let url: String?
let name: String?
let nationality: String?
}
struct Driver: Codable {
let driverId: String?
let url: String?
let givenName, familyName, dateOfBirth, nationality: String?
}
class f1TableViewController: UITableViewController {
var champions: [F1Data] = []
override func viewDidLoad() {
super.viewDidLoad()
// let jsonUrlString = "
https://api.letsbuildthatapp.com/jsondecodable/website_description"
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.title = "Champion Drivers"
fetchJSON()
}
private func fetchJSON(){
let jsonUrlString = "
https://ergast.com/api/f1/1999/driverstandings.json"
guard let url = URL(string: jsonUrlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
DispatchQueue.main.async {
if let err = err {
print("Failed to get data from url:", err)
return
}
guard let data = data else { return }
do {
let decoder = JSONDecoder()
// Swift 4.1
decoder.keyDecodingStrategy = .convertFromSnakeCase
self.champions = try decoder.decode(MRData.self, from: data)
self.tableView.reloadData()
//let season = f1Data.mrData.standingsTable.season
// let firstDriver = f1Data.mrData.standingsTable.standingsLists[0].driverStandings
// for driver in firstDriver {
//
// print("\(driver.driver.givenName) \(driver.driver.familyName)")
// }
//print(season)
} catch {
print(error)
}
}
}.resume()
}
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return champions.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellId")
let champion = champions[indexPath.row]
let driverName = champion.mrData.standingsTable.standingsLists[0].driverStandings
for driver in driverName {
cell.textLabel?.text = driver.driver.familyName
}
//cell.textLabel?.text =
//cell.detailTextLabel?.text = String(course.numberOfLessons)
return cell
}
}
Now I realize that the error is in the do catch block.
do {
let decoder = JSONDecoder()
// Swift 4.1
decoder.keyDecodingStrategy = .convertFromSnakeCase
self.champions = try decoder.decode(MRData.self, from: data)
self.tableView.reloadData()
and that the array F1Data cannot be a dictionary of MRData. So if I change it to the following self.champions = try decoder.decode([F1Data].self, from: data) the I get another error which is debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil)). Any help would be appreciated with this.
JavaScript questions and answers, JavaScript questions pdf, JavaScript question bank, JavaScript questions and answers pdf, mcq on JavaScript pdf, JavaScript questions and solutions, JavaScript mcq Test , Interview JavaScript questions, JavaScript Questions for Interview, JavaScript MCQ (Multiple Choice Questions)