I'm attempting to get certain pieces of JSON data to populate a table view, and I'm not sure how to access these properties without running into an index out of range error.
I'm getting the data from the IEX API (JSON):
fetchData(url: stockApiUrl) { (result: FetchResult<[String:Stock]>) -> (Void) in
switch result {
case .success(let object):
self.stockData = object
self.keys = Array(object.keys)
print("stockData:
(self.stockData)")
case .failure(let error):
print("Error decoding JSON:
(error)")
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
And using these structs to decode:
struct Welcome: Decodable {
let aapl, fb, msft, tsla, goog: Stock
enum CodingKeys: String, CodingKey {
case aapl = "AAPL"
case fb = "FB"
case msft = "MSFT"
case tsla = "TSLA"
case goog = "GOOG"
}
}
struct Stock: Decodable {
let quote: Quote
let news: [News]
}
struct Quote: Decodable {
let symbol: String
let companyName: String
let latestPrice: Double
}
struct News: Decodable {
let url: String
let image: String
}
The resulting data is set to a dictionary, and there's a keys
variable so I can access to keys:
var stockData = [String:Stock]()
var keys = [String]()
Accessing the properties of Stock
and Quote
is ok, but I have an array of the News
struct within Stock
, and this is what's throwing me off. My goal is to use the url
property of News
in my didSelectRow
method so I can use WebKit to load the company's url
when a cell is tapped:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let stock = stockData[keys[indexPath.row]]!
guard let webUrl = URL(string: stock.news[1].url) else {return}
print("
webUrls:
(webUrl)
")
let webController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "webController") as! WebViewController
webView.load(URLRequest(url: webUrl))
webController.view = webView
self.navigationController?.pushViewController(webController, animated: true)
}
As you can see I've attempted accessing the properties with
guard let webUrl = URL(string: stock.news[1].url) else {return}
And printing webUrl
successfully prints all of the urls, however they're all separate, as you can see here:
Because of this, webView.load(URLRequest(url: webUrl)
is only getting one url (the first one) instead of all of them, resulting in the out of range error.
I'm wondering how I can change this to get all of the url
s together instead of separate.
See Question&Answers more detail:
os