I’m having trouble deserialising a json objet in SwiftUI. I’m relatively new to both Swift and handling json.
this is the link to the json object:
https://www.reddit.com/r/all.json
here is my Data Model
import Foundation
struct first : Codable, Identifiable{
var id = UUID()
let data : second
}
struct second : Codable, Identifiable{
var id = UUID()
let children : [third]
}
struct third : Codable, Identifiable{
var id = UUID()
let data : forth
}
struct forth : Codable, Identifiable{
var id = UUID()
let title : String
let url_overridden_by_dest : String
}
and here is the code I use to deserialise the json object
mport Foundation
import SwiftUI
class ViewModel : ObservableObject {
func fetch() {
guard let url = URL(string: "https://www.reddit.com/r/all.json") else {
return
}
URLSession.shared.dataTask(with: url) { (data, _, _) in
let posts = try! JSONDecoder().decode(first.self, from: data!)
}
.resume()
}
}
the furthest I get is the following error
Expected to decode Array but found a dictionary instead.
I apologise if I am not giving enough detail, any assistance with this issue would be greatly appreciated.
CodePudding user response:
I see there are multiple issues with your codable object. First of all, make url_overridden_by_dest
property optional because it's not coming in all JSON
objects.
Make id
property constant to exclude it during decoding and add enum for coding keys.
struct first : Codable, Identifiable {
let id = UUID()
let data : Second
enum codingKeys: String, CodingKey {
case data
}
}
struct Second : Codable, Identifiable {
let id = UUID()
let children : [Third]
enum codingKeys: String, CodingKey {
case children
}
}
struct Third : Codable, Identifiable {
let id = UUID()
let data: Forth
enum codingKeys: String, CodingKey {
case data
}
}
struct Forth : Codable, Identifiable {
let id = UUID()
let title : String
let url_overridden_by_dest : String?
enum codingKeys: String, CodingKey {
case title
case url_overridden_by_dest
}
}
func fetch() {
guard let url = URL(string: "https://www.reddit.com/r/all.json") else {
return
}
URLSession.shared.dataTask(with: url) { (data, _, _) in
let posts = try! JSONDecoder().decode(first.self, from: data!)
print(posts)
}
.resume()
}
fetch()
Output
first(id: F866FA04-41AE-4EB8-A790-4BF564A17920, data: __lldb_expr_16.Second(id: D203B974-4BB8-4E16-9FF9-9620017C74A2, children: [__lldb_expr_16.Third(id: AE38D7D8-A32D-495E-A29F-7598006ECA4B, data: __lldb_expr_16.Forth(id: 3EAF0CAA-836E-406B-95BA-9CEEEEA5D0E3, title: "How this made me smile! Why representation matters", url_overridden_by_dest: Optional("https://i.redd.it/k9pb9042d9981.jpg"))), __lldb_expr_16.Third(id: 70FBDC78-C45D-49E2-8C21-E4A2BE230E29, data: __lldb_expr_16.Forth(id: 14B7DAC1-EC60-4DEA-9A2F-02FB7F5DA0BA, title: "Well, in his defense, he\'s a fucking idiot", url_overridden_by_dest: Optional("https://i.redd.it/gg1gyyofi9981.png"))), __lldb_expr_16.Third(id: 3B1AD0EB-1F01-42C8-8B7C-2C05A7CA47EA, data: __lldb_expr_16.Forth(id: 82146995-E8E4-49A1-B284-A0E757FF2A7B, title: "NASA workers making the selfie with James Webb telescope before launch.", url_overridden_by_dest: Optional("https://i.redd.it/o5jq1ajig8981.jpg"))), __lldb_expr_16.Third(id: 0B326E6E-DADF-4DE4-A11E-4F131270513F, data: __lldb_expr_16.Forth(id: 727C3AF3-151E-4125-A1C8-E5789AEE4636, title: "He wasn\'t ready.", url_overridden_by_dest: Optional("https://gfycat.com/tinycircularbellsnake"))), __lldb_expr_16.Third(id: 7750D83D-22D2-4A72-8CA8-9F277245EF7B, data: __lldb_expr_16.Forth(id: 113E0D14-43A9-451C-BF27-C9FC54D6F0CB, title: "Opening a $15,000 bottle of Petrus, 1961 with heated tools. This method is used to make sure that the cork stays intact.", url_overridden_by_dest: Optional("https://v.redd.it/7pnwlpigf8981"))), __lldb_expr_16.Third(id: 5CB01E5F-C0C2-49CE-97C7-984A8D577617, data: __lldb_expr_16.Forth(id: 458B66B3-72E6-4137-9D42-27AA2C55FB3F, title: "*checks notes*