2017-06-27 2 views
0

Ich habe eine Funktion, die JSON aus der NYTimes API liest - ich versuche, eine Tabellenansicht mit den Überschriften zu füllen. Dies ist die Funktion:Index außerhalb des Bereichs beim Versuch, ein Array von geparsten JSON zu lesen

func getJSON() { 
    let url = NSURL(string: nyTimesURL) 
    let request = NSURLRequest(url: url as! URL) 
    let session = URLSession(configuration: URLSessionConfiguration.default) 

    let task = session.dataTask(with: request as URLRequest) { (data, response, error) in 

     if error != nil { 
      print(error) 
     } 

     let json = JSON(data: data!) 
     let results = json["results"].arrayValue 

     for title in results { 

      let titles = title["title"].stringValue 
      print(titles) 

      let count: Int = title.count 
      self.numberOfStories = count 

      self.headlines.append(titles) 
      self.tableView.reloadData() 
      print("\n\n\nHeadlines array: \(self.headlines)\n\n\n") 
     } 
    } 
    task.resume() 
} 

Und dann als Klassenvariablen Ich habe

var headlines = [String]() 
var numberOfStories = 1 

Wenn ich die cell.textLabel hart codieren, kann ich die App laufen und sehen die headlines Array richtig bevölkert mit allen Schlagzeilen. Aber wenn ich versuche, das Zellenlabel auf self.headlines[indexPath.row] zu setzen, bekomme ich einen Index außerhalb des Bereichsabsturzes. Ich habe versucht, den tableView.reloadData() Aufruf in den Hauptthread (DispatchQueue.main.async{}), aber das ist nicht das Problem.

Wie kann ich die Überschriften richtig anzeigen lassen?

Danke für jede Hilfe!

EDIT: Tableview Methoden:

override func numberOfSections(in tableView: UITableView) -> Int { 
    return 1 
} 

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return self.numberOfStories 
} 


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

    cell.cellLabel.text = self.headlines[indexPath.row] 


    return cell 
} 
+0

Keiner der von Ihnen geposteten Code versucht, auf ein Array zuzugreifen. Wo nennst du eigentlich 'self.headlines [indexPath.row]'? Wann und wo nennst du 'getJSON'? – rmaddy

+0

Und Sie müssen 'DispatchQueue.main.async' verwenden, um' reloadData' aus dem Daten-Task-Vervollständigungsblock aufzurufen. – rmaddy

+0

@rmaddy Ich habe meine Tableview-Methoden hinzugefügt - ich rufe 'self.headlines [indexPath.row] 'in meiner' cellForRow'-Methode auf, um die Labels festzulegen. – KingTim

Antwort

1

Sie müssen Ihre numberOfStories Eigenschaft loszuwerden. Verwenden Sie stattdessen headlines.count.

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return headlines.count 
} 

Ihre cellForRowAt und numberOfRowsInSection müssen auf den gleichen Daten basieren.

Und stellen Sie sicher, dass Sie reloadData innerhalb DispatchQueue.main.async aufrufen, da der Datenaufgabenvervollständigungsblock aus einer Hintergrundwarteschlange aufgerufen wird.

+0

Ok, ich sehe - 'numberOfStories' war irgendwie überflüssig. Ich habe die Änderungen vorgenommen und es funktioniert jetzt, danke! Um zu bestätigen, ist 'self.tableView.ReloadData()' an der richtigen Stelle hier (in der for-Schleife)? Ich habe die "DispatchQueue.main.async" hinzugefügt, ich möchte nur sicherstellen, dass es sich in der Schleife befindet. – KingTim

+0

Eigentlich muss der Aufruf von 'reloadData' nach der for-Schleife erfolgen. Es ist sinnlos, die gesamte Tabelle für jedes hinzugefügte Element neu zu laden. Laden Sie es nach dem Hinzufügen aller Elemente einmal neu. – rmaddy

Verwandte Themen