【问题标题】:parsing json xcode swift 4解析json xcode swift 4
【发布时间】:2017-12-17 13:29:28
【问题描述】:

问题。我想从这里解析 json 并在表格视图上显示,我使用的是 swift 4 和 Decodable。但我收到类型不匹配错误。 json链接:

https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=50fb91212a47432d802b3b1ac0f717a3

我的结构看起来像这样。

    struct Root : Decodable {
    let status : String
//  let totalResults : Int
    let articles : [Article]
}

struct Article : Decodable {
    let source: Source
    let author, title, description: String
    let url: URL
//  let publishedAt: Date
    let urlToImage: String
}

struct Source: Decodable {
    let id, name: String
}

我的 ViewDidLoad 看起来像这样:

  var articles : [Article]? = []

    override func viewDidLoad() {
        super.viewDidLoad()
        tableview.delegate = self
        tableview.dataSource = self
        fetchArticles()
    }

    func fetchArticles(){
    let jsonURLString = "https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=50fb91212a47432d802b3b1ac0f717a3"
    guard let url = URL(string: jsonURLString) else { return }
      URLSession.shared.dataTask(with: url) { (data,response,err) in
           guard let data = data else { return }
            self.myArticles = [Article]()
            do{
                let decoder = JSONDecoder()
                decoder.dataDecodingStrategy = .base64
                let root = try decoder.decode(Root.self, from: data)
                self.myArticles = root.articles
                DispatchQueue.main.async {
                    self.tableview.reloadData()
                }
            } catch let error{
                print(error)
            }
        }.resume()
}

我的 cellForRowAtIndexPath

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let myCell = tableView.dequeueReusableCell(withIdentifier: "articleCell", for: indexPath) as! ArticleCell

    let article = self.myArticles[indexPath.row]
    myCell.title.text = article.title
    myCell.body.text = article.description
    myCell.author.text = article.author
    myCell.imgView.downloadImage(from: ("https://tctechcrunch2011.files.wordpress.com/2017/04/uber-vs-waymo.png"))

    return myCell
}

我遇到了错误。

No errors, nothing loads to the table view.

【问题讨论】:

    标签: json xcode swift4


    【解决方案1】:

    错误很明显。您将解码一个数组,但对象是一个字典

    这会将 JSON 解码,包括对 URLDate 的特殊解码。

    根对象是字典,键 articles 包含文章,source 是字典,而不是数组

    struct Root : Decodable {
        let status : String
        let articles : [Article]
    }
    
    struct Article : Decodable {
        let source: Source
        let author, title, description: String
        let url: URL
        let publishedAt: Date
        let urlToImage: String
    }
    
    struct Source: Decodable {
        let id, name: String
    }
    

    var articles = [Article]()
    

    do {
       let decoder = JSONDecoder()
       decoder.dateDecodingStrategy = .iso8601
       let root = try JSONDecoder().decode(Root.self, from: data)
       self.articles = root.articles
       DispatchQueue.main.async {
          self.tableview.reloadData()
       }
    } catch { print(error) }
    

    不需要使用继承自NSObject的类

    并且不要将数据源对象声明为可选并在cellForRow 中多次获取相同的项目,它是indexPath.row

     ...
     let article = self.articles[indexPath.row]
     myCell.title.text = article.title
     myCell.body.text = article.description
     myCell.author.text = article.author
     ...
    

    【讨论】:

    • 好的,我按照你的评论改了,还是!
    • 我已经在上面的问题中发布了新代码。请您检查一次。现在没有错误,我理解了这个问题。但是为什么表格视图没有加载!
    • 请不要用答案中的建议来编辑更新代码的问题。它可能会使其他读者感到困惑。而且 – 顺便说一句 – 您没有考虑我将数据源数组声明为非可选的建议。我犯了一个错误。 root.articles 必须分配给 self.articles。我更新了答案。
    • 万岁!非常感谢,我现在明白了这个问题,对于要查看这个问题的人,请看我已经用工作代码更新了这个问题。很抱歉混淆了。我试图在我的课堂上发布 107 行代码作为答案,但它没有让我!
    • 不要那样做。这个问题变得毫无意义,因为在编辑代码后,您将不会再遇到问题中所述的类型不匹配,并且其他人无法重现该问题及其解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-30
    • 1970-01-01
    相关资源
    最近更新 更多