I am having a minor issue parsing the JSON from reddit.
Simplified reddit JSON response:
{
"kind": "Listing",
"data": {
"after": "t3_c2wztu",
"before": null,
"children": [
{
"data": {
"all_awardings": [],
"approved_at_utc": null,
"approved_by": null
},
"kind": "t3"
}
],
"dist": 25,
"modhash": ""
}
}
I simplified the JSON as it can get 4000 lines long, mostly repeating children objects.
When we look at the second "data" key inside the "children" object, that's when we get all the needed data, like images, usernames, etc..
My structs in Swift are as follows: Seeing that the JSON is nested, I believe I need to create either nested structs or multiple structs to help drill down through the JSON. Am I correct I that?
struct Model: Decodable {
let data : Children?
enum CodingKeys: String, CodingKey {
case data = "data"
}
}
struct Children: Decodable {
let data: [Child]?
enum CodingKeys: String, CodingKey {
case data = "data"
}
}
//MARK - there is MORE than author and full name, we are just doing this for ease of parsing.
struct Child: Decodable {
let author : String?
let authorFullname : String?
enum CodingKeys: String, CodingKey {
case author = "author"
case authorFullname = "author_fullname"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
author = try values.decodeIfPresent(String.self, forKey: .author)
authorFullname = try values.decodeIfPresent(String.self, forKey: .authorFullname)
}
}
Now here is my URLSession call:
class NetworkManager {
static var shared: NetworkManager = { return NetworkManager() }()
private init(){}
public func getFrontPage(completion: @escaping (Model?) -> Void) {
guard let url = URL(string: "https://www.reddit.com/r/all/.json") else { fatalError("Invalid URL") }
URLSession.shared.dataTask(with: url) { data, response, err in
if(err != nil) {
completion(nil)
}
guard let httpResponse = response as? HTTPURLResponse else { fatalError("URL Response Error") }
switch httpResponse.statusCode {
case 200:
if let data = data {
do {
let data = try JSONDecoder().decode(Model.self, from: data)
completion(data)
} catch {
print("ERROR DECODING JSON \(err.debugDescription)")
}
}
break
default:
completion(nil)
break
}
}.resume()
}
And finally in ViewDidLoad:
var redditData = [Model]()
override func viewDidLoad() {
super.viewDidLoad()
NetworkManager.shared.getFrontPage { (items) in
// self.redditData = items?.data
print(items)
DispatchQueue.main.async {
// update the UI
}
}
}
Heres my current error I can't get past:
self.redditData = items?.data gives me an error:
Cannot assign value of type 'Children?' to type '[Model]'
Questions: 1. is my struct layout right? Don't worry about the actual data, like usernames and all, I shortened it for this post.
am I "drilling" down through the JSON correctly in my network manager function?
How do I fix my error in my viewController class?
Sorry for such a long topic!!