解析json xcode swift 4

Posted

技术标签:

【中文标题】解析json xcode swift 4【英文标题】:parsing 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.

【问题讨论】:

【参考方案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 行代码作为答案,但它没有让我! 不要那样做。这个问题变得毫无意义,因为在编辑代码后,您将不会再遇到问题中所述的类型不匹配,并且其他人无法重现该问题及其解决方案。

以上是关于解析json xcode swift 4的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Swift 2 + XCode 7 + iOS 9 获取和解析 JSON [重复]

使用 Alamofire Swift 3 和 Xcode 8 beta 解析 JSON 没有数据

使用 Swift (NSArray) 解析 JSON

使用 Decodeable swift 4.0 解析数据不读取数据 - Xcode

在 Swift 中使用 nil 值解析 JSON

在 Swift 3 中正确解析 JSON