2017-12-30 37 views
0

Ich versuche, die Daten von func getCoinData auf ein Array sympolsCoin und Array sympolsCoin zu speichernSwift 4 Speichern von Daten von json zu einem Array zu zeigen, in einer Tabellen-

in meinem Tableview verwenden

Ich schaffe diese Klasse in die gleiche ViewController.swift Datei:

struct Coin: Decodable { 

let symbol : String 
let price_usd : String } 

Und dies in meiner Ansicht Controller-Klasse:

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() 
} 

Und wenn ich das Array in meinem Tableview verwende ich bekam leere Tabelle!

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 

} 

Antwort

0

einen Ausgang von Tableview in Viewcontroller Klasse erstellen und geben Sie es "Tableview" nennen dann Versuchen Sie diesen Code: 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() 
} 

Rufen Sie diese Funktion in ViewDidLoad wie diese

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

Ich habe ein kleines Problem. .wenn die App nichts in der Tabellenansicht anzeigt, bis ich nach unten oder oben scrolle, dann zeigen die Daten! – cs4alhaider

+0

bitte warten i auf Ihre Frage wird Arbeits –

+0

gehen Sie zu Ihrem getCoinData() ersetzen "self.tableView.reloadData()" mit DispatchQueue.main.async { self.tableView.reloadData() } –

0

Sie müssen das TableView vom Hauptthread aktualisieren. Als eine gute Lektion zu lernen: Immer die Benutzeroberfläche vom Hauptthema aktualisieren. Immer.

Es gibt jedoch ein anderes Problem mit Ihrem Code, wie Sie Ihre Etiketten Setup nicht funktionieren wird. TableViewCells werden wiederverwendet, also nehme ich an, dass Sie @IBOutlets für sie woanders haben. Was sollten Sie tun, ist eine Bezeichnung Konstante in cellForRowAt erklären:

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] 
} 

Der obige Code Sie haben Setup zwei Etiketten mit den Tags 100 und 101 in der Storyboard geht davon aus (vorausgesetzt, Sie eine verwenden)

+0

ich ein kleines Problem haben ..wenn die App nichts in der Tabellenansicht auftaucht, bis ich nach unten oder oben scrolle, dann zeigen sich die Daten! PROBLEM gelöst wenn ich DispatchQueue.main verwende.async { selb.tableView.ReloadData() } hat gut funktioniert, danke – cs4alhaider

+0

Großartig. Sie sollten tiefer in Threading hineinschauen. Es ist interessant, leistungsstark und wichtig für die Aktualisierung der Benutzeroberfläche. Fühlen Sie sich auch frei, dies als die richtige Antwort zu akzeptieren. – returnVoid

1

Da Sie verwenden JSONDecoder die gesamte Logik zum Erstellen und Bestücken sympolsCoin und priceUSDcoin ist sinnlos und redundant.

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

var coins = [Coin]() 

Der Abschluss-Handler ist überflüssig, zu. nachladen nur die Tabellen-Ansicht auf dem Hauptthread nach Empfang der Daten:

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() 
} 

In viewDidLoad lädt die Daten

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

In cellForRow Update die Benutzeroberfläche

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 

} 
Verwandte Themen