Swift 4将数据从json保存到数组中以在TableView中显示它

问题描述 投票:1回答:3

我正在尝试将数据从func getCoinData保存到数组sympolsCoin和数组sympolsCoin以在我的TableView中使用它

我在相同的ViewController.swift文件中创建此类:

struct Coin: Decodable {

let symbol : String
let price_usd : String } 

这在我的View控制器类中:

var coins = [Coin]()


var sympolsCoin = [String]()
var priceUSDcoin = [String]()



func getCoinData(completion: @escaping () -> ()) {
    let jsonURL = "https://api.coinmarketcap.com/v1/ticker/"
    let url = URL(string: jsonURL)

    URLSession.shared.dataTask(with: url!) { (data, response, error) in

        do {
            self.coins = try JSONDecoder().decode([Coin].self, from: data!)

            for info in self.coins {

                self.sympolsCoin.append(info.symbol)
                self.priceUSDcoin.append(info.price_usd)

                print("\(self.sympolsCoin) : \(self.priceUSDcoin)")

                completion()
            }

        }


        catch {
            print("Error is : \n\(error)")
        }
    }.resume()
}

当我在TableView中使用数组时,我得到了空白表!

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "BitcoinTableViewCell", for: indexPath) as! BitcoinTableViewCell

    cell.coinNameLable.text = sympolsCoin[indexPath.row]
    cell.priceLable.text = priceUSDcoin[indexPath.row]

    return cell

}
json swift uitableview tableview swift4
3个回答
1
投票

在ViewController类中创建tableView的出口并将其命名为“tableView”然后尝试此代码:Swift 4

func getCoinData() {
    let jsonURL = "https://api.coinmarketcap.com/v1/ticker/"
    let url = URL(string: jsonURL)

    URLSession.shared.dataTask(with: url!) { (data, response, error) in

        do {
            self.coins = try JSONDecoder().decode([Coin].self, from: data!)

            for info in self.coins {

                self.sympolsCoin.append(info.symbol)
                self.priceUSDcoin.append(info.price_usd)

                print("\(self.sympolsCoin) : \(self.priceUSDcoin)")

                self.tableView.reloadData()
            }

        }

        catch {
            print("Error is : \n\(error)")
        }
  }.resume()
}

像这样在ViewDidLoad中调用此函数

 override func viewDidLoad() {
    super.viewDidLoad()
    getCoinData()
}

3
投票

因为你正在使用JSONDecoder创建和填充sympolsCoinpriceUSDcoin的整个逻辑是毫无意义和冗余的。

struct Coin: Decodable {
    private enum CodingKeys: String, CodingKey {
        case symbol, priceUSD = "price_usd"
    }
    let symbol : String
    let priceUSD : String 
} 

var coins = [Coin]()

完成处理程序也是多余的。只需在收到数据后重新加载主线程上的表视图:

func getCoinData() {
    let jsonURL = "https://api.coinmarketcap.com/v1/ticker/"
    let url = URL(string: jsonURL)

    URLSession.shared.dataTask(with: url!) { [unowned self] (data, response, error) in
        guard let data = data else { return }
        do {
            self.coins = try JSONDecoder().decode([Coin].self, from: data)
            DispatchQueue.main.async {
               self.tableView.reloadData()
            }

        } catch {
            print("Error is : \n\(error)")
        }
    }.resume()
}

viewDidLoad中加载数据

override func viewDidLoad() {
    super.viewDidLoad()
    getCoinData()
}

cellForRow更新UI

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "BitcoinTableViewCell", for: indexPath) as! BitcoinTableViewCell

    let coin = coins[indexPath.row]
    cell.coinNameLable.text = coin.symbol
    cell.priceLable.text = coin.priceUSD

    return cell

}

2
投票

您需要从主线程更新tableView。作为一个值得学习的好教训:始终从主线程更新UI。总是。

do {
        self.coins = try JSONDecoder().decode([Coin].self, from: data!)

        for info in self.coins {

            self.sympolsCoin.append(info.symbol)
            self.priceUSDcoin.append(info.price_usd) 

            DispatchQueue.main.async {
                self.tableView.reloadData()
            }

            print("\(self.sympolsCoin) : \(self.priceUSDcoin)")

            completion()
        }

    }

但是,您的代码的另一个问题是您的标签设置方式不起作用。 TableViewCells被重用了,所以我猜你在其他地方有@IBOutlets。你应该做的是在cellForRowAt中声明一个标签常量:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)

    let coinNameLabel = cell.viewWithTag(100) as! UILabel
    coinNameLabel.text = sympolsCoin[indexPath.row]
    let priceNameLabel = cell.viewWithTag(101) as! UILabel
    priceNameLabel.text = priceUSDcoin[indexPath.row]
}

上面的代码假设您在故事板中设置了标签100和101的两个标签(假设您使用的是标签)

© www.soinside.com 2019 - 2024. All rights reserved.