【问题标题】:Deserialize complex JSON using Alamofire and Swift 3使用 Alamofire 和 Swift 3 反序列化复杂的 JSON
【发布时间】:2017-05-26 09:39:47
【问题描述】:

如何反序列化这个 JSON 并在 tableView 中显示标题 JSON:https://www.healthcare.gov/api/articles.json

到目前为止我所尝试的:

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
}

服务器状态码是 200,所以我知道我的请求没问题。问题是我不知道如何创建合适的数据模型。

【问题讨论】:

    标签: ios json swift alamofire


    【解决方案1】:

    JSON 令人困惑,因为在 articles 数组的末尾(应该只包含字典)有一个布尔值 false,因此向下转换为 [[String:Any]] 失败。

    你必须flatMap数组忽略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()
        }
    

    并且键mainTitle在JSON中不存在,在Newsinit方法中你必须写(字典是[String:Any]而不是[string:String]

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

    【讨论】:

    • 你对parsedData是什么意思,它不存在但你把它分配给文章,编译器不让我运行它。
    • 但是现在我的应用程序崩溃了,因为在这一行展开时有一个 nil self.newsData.append(News(dictionary: news as! [String : String] ))
    • 字典是[String:Any]。我更新了答案。并删除强制向下转换。
    【解决方案2】:

    为了快速处理 JSON,我建议你使用 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()
        }
    }
    

    现在您可以遍历 myJson 并调整 tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) 以检索您的结果

    【讨论】:

    • 但是我怎样才能只提取标题呢?此外,您正在分配没有 JSON 信息的 response.result,它只有服务器标头。 JSON 可以在 response.result.value 下找到,但我不需要遍历整个数组,我只需要标题。
    【解决方案3】:

    用这个替换你的函数。

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

    您可以在http://www.jsoneditoronline.org/获得可读的 JSON

    【讨论】:

      【解决方案4】:

      尝试将您的响应映​​射到数据模型。然后你不需要反序列化你的 json。 https://github.com/insanoid/SwiftyJSONAccelerator 将帮助您创建数据模型。

      【讨论】:

      • 你说Try to map your response to a data model. 但 OP 已经在说“问题是我不知道如何创建合适的数据模型”。他们已经知道他们应该这样做。他们在问如何做到这一点。
      猜你喜欢
      • 2020-10-19
      • 1970-01-01
      • 2011-05-09
      • 2018-12-14
      • 2020-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多