我正在尝试将数据从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
}
在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()
}
因为你正在使用JSONDecoder
创建和填充sympolsCoin
和priceUSDcoin
的整个逻辑是毫无意义和冗余的。
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
}
您需要从主线程更新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的两个标签(假设您使用的是标签)