Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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:

enter image description 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 urls together instead of separate.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
151 views
Welcome To Ask or Share your Answers For Others

1 Answer

ok, so basicly you struggle to iterate over an array if I understand it correct, here you are:

var urls = [String]()
stock.news.forEach { urls.append($0.url) }
print(urls)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...