Colin Miller
Colin Miller

Reputation: 51

How to decode a nested JSON in Swift?

I'm currently working on a project that makes an API call and returns and decodes a JSON response. It needs to access information deep within a nested json (the URL for the response is https://waterservices.usgs.gov/nwis/iv/?format=json&indent=on&sites=08155200&parameterCd=00065&siteStatus=all). I've figured out how to decode the first level/non-nested parts of the json with this code:

import UIKit

struct Post: Codable {
    let name: String
}

let url = URL(string: "https://waterservices.usgs.gov/nwis/iv/?format=json&indent=on&sites=08155200&parameterCd=00065&siteStatus=all")!

URLSession.shared.dataTask(with: url) { data, _, _ in
    if let data = data {
        let posts = try! JSONDecoder().decode(Post.self, from: data)
        print(posts)
    }
}.resume()

which then responds with this output (which is what I wanted):

Post(name: "ns1:timeSeriesResponseType")

However, the code I wrote to decode the nested parts of the file:

import UIKit

struct queryInfo: Codable {
    let queryURL: String

    private enum CodingKeys: String, CodingKey {
        case queryURL = "queryURL"
    }
}

struct Values: Codable {
    let queryinfo: queryInfo

    private enum CodingKeys: String, CodingKey {
        case queryURL = "queryInfo"
    }
}

struct Post: Codable {
    let name: String
    //let scope: String
    let values: Values
    //let globalScope: Bool //true or false
}

let url = URL(string: "https://waterservices.usgs.gov/nwis/iv/?format=json&indent=on&sites=08155200&parameterCd=00065&siteStatus=all")!

URLSession.shared.dataTask(with: url) { data, _, _ in
    if let data = data {
        let posts = try! JSONDecoder().decode(Post.self, from: data)
        print(posts)
    }
}.resume()

responds with error:

ParseJSON.playground:11:8: error: type 'Values' does not conform to protocol 'Decodable'
struct Values: Codable {
       ^

ParseJSON.playground:15:14: note: CodingKey case 'queryURL' does not match any stored properties
        case queryURL = "queryInfo"
             ^

error: ParseJSON.playground:11:8: error: type 'Values' does not conform to protocol 'Encodable'
struct Values: Codable {
       ^

ParseJSON.playground:15:14: note: CodingKey case 'queryURL' does not match any stored properties
        case queryURL = "queryInfo"
             ^

Upvotes: 0

Views: 164

Answers (1)

Faysal Ahmed
Faysal Ahmed

Reputation: 7669

As @Larme already mention on the comment. You have to update this portion to fix this issue.

struct Values: Codable {
    let queryinfo: queryInfo

    private enum CodingKeys: String, CodingKey {
        case queryinfo = "queryInfo"
    }
}

To get more you can try https://app.quicktype.io/ to generate the decodable code from any json.

Upvotes: 1

Related Questions