2017-05-26 7 views
2

Wie kann ich dieses JSON deserialisieren und die Titel in einem Tableview JSON anzuzeigen: https://www.healthcare.gov/api/articles.jsonDeserialize komplexe JSON mit Alamofire und Swift 3

Was ich bisher versucht:

struct News { 
    let title : String 

    init(dictionary: [String:String]) { 
     self.title = dictionary["mainTitle"] ?? "" 
    } 
} 

var newsData = [News]() 

func downloadData() { 
    Alamofire.request("https://www.healthcare.gov/api/articles.json").responseJSON { response in 
     print(response.request as Any) 
     print(response.response as Any) 
     print(response.data as Any) 
     print(response.result.value) 

     self.newsData.removeAll() 
     if let json = response.result.value as? [[String:String]] { 
      for news in json { 
       self.newsData.append(News(dictionary: news)) 
      } 
      self.tableView.reloadData() 
     } 
    } 
} 

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

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
} 

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

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

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 
    let news = newsData[indexPath.row] 
    cell.textLabel?.text = news.title 
    return cell 
} 

Der Status Server-Code ist 200, also weiß ich, dass meine Anfrage in Ordnung ist. Die Sache ist, dass ich nicht weiß, wie ich ein richtiges Datenmodell schaffen kann.

Antwort

1

Die JSON ist verwirrend, weil am Ende der articles Array - die nur Wörterbücher enthalten soll - gibt es einen einzigen Boolean false so nach [[String:Any]] niedergeschlagen schlägt fehl.

Sie müssen flatMap das Array die Bool

if let json = response.result.value as? [String:Any], 
     let articles = json["articles"] as? [Any] { 
      for news in articles.flatMap({$0 as? [String:Any]}) { 
       self.newsData.append(News(dictionary: news)) 
      } 
      self.tableView.reloadData() 
    } 

und den Schlüssel mainTitle existieren im JSON, in der init Methode von News Sie schreiben, muss nicht ignorieren (das Wörterbuch [String:Any] statt [string:String])

init(dictionary: [String:Any]) { 
    self.title = dictionary["title"] ?? "" 
} 
+0

Was meintest du mit parsedData, es existiert nicht, aber du hast es Artikeln zugewiesen, der Compiler lässt es nicht laufen. –

+0

Durch schlecht, habe ich die Antwort bearbeitet. – vadian

+0

Aber jetzt stürzt meine App ab, weil es eine Null beim Auspacken auf dieser Linie gibt self.newsData.append (Nachrichten (Wörterbuch: Nachrichten als! [String: String])) –

1

Um JSON in Swift zu behandeln, empfehle ich SwiftyJSON. (https://github.com/SwiftyJSON/SwiftyJSON)

var myJson : JSON 
func downloadData() { 
    Alamofire.request("https://www.healthcare.gov/api/articles.json").responseJSON { response in 
     print(response.request as Any) 
     print(response.response as Any) 
     print(response.data as Any) 
     print(response.result.value) 
     self.myJson = JSON(response.result.value) 
     self.tableView.reloadData() 
    } 
} 

jetzt können Sie durch myJson iterieren und passen tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) Ihr Ergebnis mit diesem

+0

Aber wie kann ich nur Titel extrahieren? Außerdem weisen Sie response.result zu, das keine JSON-Informationen enthält, sondern nur Server-Header. Der JSON kann unter response.result.value gefunden werden, aber ich brauche nicht das ganze Array zu durchlaufen, ich brauche nur Titel. –

0

Ersetzen Sie Ihre Funktion abzurufen.

func downloadData() { 
      Alamofire.request("https://www.healthcare.gov/api/articles.json").responseJSON { response in 
       print(response.request as Any) 
       print(response.response as Any) 
       print(response.data as Any) 
       print(response.result.value) 

       self.newsData.removeAll() 
       if let json = response.result.value as? [String:AnyObject] //As outermost object in your JSON file is a dictionary 
       { 
        let article = json["articles"] as? [[String:AnyObject]] //Here you need to get inner object which is value for key "articles" 
        for news in article { 
         self.newsData.append(News(dictionary: news)) 
        } 
        self.tableView.reloadData() 
       } 
      } 
     } 

können Sie lesbar JSON erhalten bei http://www.jsoneditoronline.org/

0

Versuchen Sie, Ihre Antwort auf ein Datenmodell abzubilden. Dann müssen Sie Ihren JSON nicht deserialisieren. https://github.com/insanoid/SwiftyJSONAccelerator hilft Ihnen bei der Erstellung Ihres Datenmodells.

+0

Sie sagen 'Versuchen Sie, Ihre Antwort auf ein Datenmodell abzubilden. Aber OP sagt bereits:" Die Sache ist, dass ich nicht weiß, wie ich ein richtiges Datenmodell erstellen kann ". Sie wissen bereits, dass sie das tun sollten. Sie fragen * wie * es zu tun. – Moritz