I have this JsonResponse from the server
{
"status": "ok",
"totalResults": 0,
"articles": [
{
"title": "United places order for 200 Boeing planes, giving two troubled jets a vote of confidence - CNN",
"author": "Chris Isidore",
"source": {
"Id": "cnn",
"Name": "CNN"
},
"publishedAt": "2022-12-13T14:33:00Z",
"url": "https://www.cnn.com/2022/12/13/business/united-boeing-order/index.html"
},
{
"title": "November CPI: Inflation rose at annual 7.1% over last year - Yahoo Finance",
"author": "Alexandra Semenova",
"source": {
"Id": null,
"Name": "Yahoo Entertainment"
},
"publishedAt": "2022-12-13T14:17:04Z",
"url": "https://finance.yahoo.com/news/november-cpi-inflation-rises-71-over-last-year-141704528.html"
},
{
"title": "Gold prices jump higher as U.S. CPI rises 7.1% in November - Kitco NEWS",
"author": "http://www.facebook.com/kitconews",
"source": {
"Id": null,
"Name": "Kitco NEWS"
},
"publishedAt": "2022-12-13T13:37:00Z",
"url": "https://www.kitco.com/news/2022-12-13/prices-jump-higher-as-U-S-CPI-rises-7-1-in-November.html"
},
]
And here is my model struct
struct Article: Codable {
let articles: [ArticleElement]
}
// MARK: - ArticleElement
struct ArticleElement: Codable {
let title: String
let author: String?
let source: Source
let publishedAt: Date
let url: String
}
// MARK: - Source
struct Source: Codable {
let id: String?
let name: String
enum CodingKeys: String, CodingKey {
case id = "Id"
case name = "Name"
}
}
I get the error that the codingKey ("articles") is not found, here's the full error message:
keyNotFound(CodingKeys(stringValue: "articles", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: "articles", intValue: nil) ("articles").", underlyingError: nil))
I have tried to fetch this API and it's returning this error. I have all the required keys and Idk why I am receiving this error.
here is the API I am fetching "https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=(apiKey)" Here's the function that does the API call to the server and decodes the JSON
func fetch<T: Decodable>(request: Request, type:T.Type,
callback: @escaping (Result<T, Error>)->Void) {
var urlComponnets = URLComponents(string: request.baseUrl + request.path)
var queryItems:[URLQueryItem] = []
for (k, v) in request.params {
queryItems.append( URLQueryItem(name: k, value: v))
}
urlComponnets?.queryItems = queryItems
let urlsesson = URLSession.shared
guard let url = urlComponnets?.url else { return }
let urlReuqest = URLRequest(url: url)
let dataTask = urlsesson.dataTask(with: urlReuqest) { data, responce, error in
let jsonDecoder = JSONDecoder()
jsonDecoder.dataDecodingStrategy = .deferredToData
do {
let responce = try jsonDecoder.decode(type, from: data!)
callback(.success(responce))
} catch {
callback(.failure(error))
}
}
dataTask.resume()
}
And I am calling the fetch function from the viewModel as such
func getArticles(){
let request = Request(baseUrl:"https://newsapi.org", path:"/v2/top-headlines?country=us&category=business&apiKey=\(ApiKey)", params: [:], type: "GET", header: [:])
networkManager.fetch(request: request, type: Article.self) { result in
switch result {
case .success(let article):
self.articles = article.articles
case .failure(let error):
print(error)
}
}
}
where
var articles: [ArticleElement] = []
Solved by passing all parameters using the params
argument (instead of hardcoding them in the path
argument):
let request = Request(baseUrl:"https://newsapi.org", path:"/v2/top-headlines?", params: ["country":"us", "category":"business", "apiKey":"ee55178ed2fb43b0a2a721d43d99a5b0"], type: "GET", header: [:])