Home > other >  "Expected to decode Array<Any> but found a dictionary instead." How can i solve this
"Expected to decode Array<Any> but found a dictionary instead." How can i solve this

Time:12-06

i'm trying to do with API Call. I got error every time trying to do API Call.

typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))

this is what i see when simulate my code in console.

Here is json format i try to call in my app. Click

My Model

struct Article: Codable {
    let author: String
    let title, articleDescription: String
    let url: String
    let urlToImage: String
    let publishedAt: Date
    let content: String?

    enum CodingKeys: String, CodingKey {
        case  author, title
        case articleDescription = "description"
        case url, urlToImage, publishedAt, content
    }
}

and This is my API Call function.


import UIKit

class ViewController: UIViewController {

    var article = [Article]()
    override func viewDidLoad() {
        super.viewDidLoad()
        jsonParse {
            print("success")
        }
        view.backgroundColor = .red
    }


    
    
    func jsonParse(completed: @escaping () -> ()) {
        
        let url = URL(string: "https://newsapi.org/v2/top-headlines?country=tr&apiKey=1ea9c2d2fbe74278883a8dc0c9eb912f")
 
        let task =  URLSession.shared.dataTask(with: url!) { data, response, error in
            
            if error != nil {
                print(error?.localizedDescription as Any)
            }else {
                
                do {
                    let result = try JSONDecoder().decode([Article].self, from: data!)
                    DispatchQueue.main.async {
                        print(data as Any)
                        print("success")
                        self.jsonParse {
                            print("success")
                        }
                    }
                   
                }catch {
                    print(error.localizedDescription)
                }
          
            }
            
        }
        task.resume()
        
        
    }
    
}

Can you help me about my problem, thank you.

CodePudding user response:

This is a very common mistake: You ignore the root object, a dictionary. With Decodable it's mandatory to decode the JSON from the top.

Add this struct

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

and decode

let result = try JSONDecoder().decode(Response.self, from: data!)

And never print(error.localizedDescription) in a Codable catch block. Always write this

} catch {
    print(error)
}
  • Related