Reputation: 339
For my first Swift UIKit app, I am trying to parse some JSON data and use it to populate a UITableView. Ideally, the table view would update with changes to the JSON but this is not entirely necessary right now as the JSON will change very infrequently.
But I'm having some issues parsing the JSON - I seem to be getting an empty array...
The code in my main View Controller
import Foundation
import UIKit
//TODO - JSON
struct Visualisation: Codable {
var id: Int
let name, info, url_name, tags: String
}
/*
JSON:
[
{
"id": 0,
"name": "Two Body Collision",
"info": "A 2D body collision under the elastic collision assumption",
"url_name": "https://www.imperialvisualisations.com/visualisations/two-body-collision/two-body-collision/",
"tags": "Physics, Mechanics"
},
{
"id": 1,
"name": "Waves in Dielectrics",
"info": "The effect of incidence angle & refractive index of dielectric on reflection & transmission",
"url_name": "https://www.imperialvisualisations.com/visualisations/2d-and-3d-coordinate-systems/2d-polar-coordinates/",
"tags": "Physics, Maths, Matrices, Linear algebra"
}
]
This is the structure I am aiming for:
var visualisations: [Visualisation] = [
.init(id:0, name: "Two Body Collision", info: "A 2D body collision under the elastic collision assumption", url_name: "https://www.imperialvisualisations.com/visualisations/two-body-collision/two-body-collision/", tags: "Physics, Mechanics"),
.init(id:2, name: "Waves in Dielectrics", info: "The effect of incidence angle & refractive index of dielectric on reflection & transmission", url_name: "https://www.imperialvisualisations.com/visualisations/single-wave-in-3d/boundry-conditions/", tags: "Physics, Electromagnetism, Light, Refractive index, Angle of incidence")
]
*/
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var visualisations = [Visualisation]()
override func viewDidLoad() {
super.viewDidLoad()
guard let url = URL(string: "https://api.myjson.com/bins/1ao7in") else { fatalError("JSON URL not found") }
URLSession.shared.dataTask(with: url) { (data, _, _) in
guard let data = data else { fatalError("JSON data not loaded") }
guard let decodedVisualisations = try? JSONDecoder().decode([Visualisation].self, from: data) else { fatalError("Failed to decode JSON")}
DispatchQueue.main.async{
self.visualisations = decodedVisualisations
}
}.resume()
print("visualisations")
print(visualisations)
tableView.delegate = self
tableView.dataSource = self
navigationController?.navigationBar.prefersLargeTitles = true
title = "Visualisations"
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return visualisations.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//visualisation at row in view
let visualisation = visualisations[indexPath.row]
//recast! ??
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell") as! TableViewCell
cell.setCell(visualisation: visualisation)
//set Cell just sets the elements of the table cell in another file
return cell
}
}
I am not getting any error messages however the decoding seems to be doing nothing to the 'visualisations' array.
Any help would be appreciated - thanks.
Upvotes: 1
Views: 972
Reputation: 129
As per @vadian commented, this works just fine.
struct Visualisation: Codable {
var id: Int
let name, info, url_name, tags: String
}
class ViewController: UIViewController {
var visualisations = [Visualisation]()
override func viewDidLoad() {
super.viewDidLoad()
guard let url = URL(string: "https://api.myjson.com/bins/1ao7in") else { fatalError("JSON URL not found") }
URLSession.shared.dataTask(with: url) { (data, _, _) in
guard let data = data else { fatalError("JSON data not loaded") }
do {
let decodedVisualisations = try JSONDecoder().decode([Visualisation].self, from: data)
self.visualisations = decodedVisualisations
} catch let error {
debugPrint(error.localizedDescription)
}
}.resume()
}
}
Upvotes: 1