-1

Problem. I want to parse the json from here and show on a table view, i am using swift 4 and Decodable. but i am getting a type mismatch error. Link to json:

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

My Struct looks like this.

    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
}

My ViewDidLoad Looks like this :

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

My 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
}

Error i am getting.

No errors, nothing loads to the table view.
0

1 Answer 1

0

The error is clear. You are going to decode an array but the object is a dictionary.

This decodes the JSON including the special decoding to URL and Date.

The root object is a dictionary, the key articles contains the articles and source is a dictionary, not an array

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

There is no need to use classes inheriting from NSObject

And do not declare the data source object as optional and get the same item a couple of times in cellForRow and it's indexPath.row

 ...
 let article = self.articles[indexPath.row]
 myCell.title.text = article.title
 myCell.body.text = article.description
 myCell.author.text = article.author
 ...
Sign up to request clarification or add additional context in comments.

8 Comments

OK, i changed as per your comment, still !
I have posted the new code in the question above. Can you please check once. Now there is no error and i understood the problem. But why table view is not loading!
Please don't edit the question updating the code with suggestions in answers. It could confuse other readers. And – btw – you didn't consider my suggestion to declare the data source array as non-optional. I made a mistake. root.articles must be assigned to self.articles. I updated the answer.
Hurray! thanks a lot, i understood the problem now, for people who are going to look at the question, please see that i have updated the question with working code. Sorry for the mix up. I tried to post the 107 lines of code in my class in answer but it did not let me!
Don't do that. The question became pointless because after editing the code you won't get a type mismatch anymore as stated in the question and others can't reproduce the issue and its solution.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.