I am working with an api and getting back some strangely formatted JSON.
[
{
"title": "Wales' new £2bn space strategy hopes",
"url": "https://www.bbc.co.uk/news/uk-wales-60433763",
"source": "bbc"
},
{
"title": "Could Port Talbot become a centre of space tech? Video, 00:02:02Could Port Talbot become a centre of space tech?",
"url": "https://www.bbc.co.uk/news/uk-wales-60471170",
"source": "bbc"
},
]
As you can see, there is no object name I can latch on to. I've tried making a model like this
struct SpaceNewsModel: Identifiable, Codable {
var id = UUID()
let title: String
let url: String
let source: String
}
But once I get to using JSONDeocder()
with the following code
let decoder = JSONDecoder()
if let safeData = data {
do {
let astroNews = try decoder.decode(SpaceNewsModel.self, from: safeData)
print(astroNews)
} catch {
print("DEBUG: Error getting news articles \(error.localizedDescription)")
}
}
I get the error DEBUG: Error getting news articles The data couldn’t be read because it isn’t in the correct format.
So how would you go about printing out each title, url, or source to the console? I've worked with JSON before and they are usually formatted differently.
CodePudding user response:
I found a workaround for this. Removing the identifiable protocol lets me access the data. Like so
struct SpaceNewsModel: Codable {
let title: String
let url: String
let source: String
}
Then I can use decoder as normal
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
if error != nil {
print(error!)
} else {
let decoder = JSONDecoder()
if let safeData = data {
do {
let astroNews = try decoder.decode([SpaceNewsModel].self, from: safeData)
print(astroNews[0].title)
} catch {
print("DEBUG: Error getting news articles \(error)")
}
}
I did change let astroNews = try decoder.decode(SpaceNewsModel.self, from: safeData)
to let astroNews = try decoder.decode([SpaceNewsModel].self, from: safeData)
Even with changing it to array type or not, as long as I had my SpaceNewsModel following the identifiable protocol, it would NOT work. It's a strange workaround, but it works for now.
CodePudding user response:
in addition to
let astroNews = try decoder.decode([SpaceNewsModel].self, from: safeData)
use this for your SpaceNewsModel
and
struct SpaceNewsModel: Identifiable, Codable {
let id = UUID() // <-- here, a let
let title: String
let url: String
let source: String
enum CodingKeys: String, CodingKey { // <-- here
case title,url,source
}
}