简体   繁体   中英

Codable Swift JSON Parsing Nested JSON

I have JSON data that looks like this

{
    "latitude": 34.088051,
    "longitude": -118.296512,
    "timezone": "America/Los_Angeles",
    "daily": {
        "summary": "No precipitation throughout the week, with high temperatures rising to 92°F on Friday.",
        "icon": "clear-day",
        "data": [
            {
                "time": 1535266800,
                "summary": "Mostly cloudy in the morning.",
                "icon": "partly-cloudy-day",
                "sunriseTime": 1535289854,
                "sunsetTime": 1535336915,
                "moonPhase": 0.51}

I want to pull the time, summary, icon from this.

I create a class of type WeatherObject, but that's where I get stuck. How do I create the struct(s)? The keys are not snake cased or badly named so I think I can get away without using an enum to rename the variable names.

EDIT: Do - Catch falling through to catch. VC implements protocol. Data passed to protocol method prints in method implementation, but fails to process in do clause.

protocol NetworkingDelegate: AnyObject {
    func didGetResult(data: Data?) -> Void
}


class Networking: NSObject {

    var data: Data?
    weak var delegate: NetworkingDelegate?

    func makeAPIRequest(apiString: String) -> Void {
        guard let url: URL = URL(string: apiString) else{
            print("ERROR no URL")
            return
        }

        let urlRequest = URLRequest(url: url)

        let dataSession = URLSession.shared
        let dataTask = dataSession.dataTask(with: urlRequest) { (data, response, error) in

            guard error == nil else{
                print("ERROR found in networking call")
                print(error!)
                return
            }

            if data != nil{

                print("Data exists in networking")
                self.delegate?.didGetResult(data: data!)




            }else{
                print("ERROR: did not receive data")
            }
        }

        dataTask.resume()
    }


}

In ViewController

  func didGetResult(data: Data?) {



            do {

                if let dataObject = data{

                    let theString:NSString = NSString(data: dataObject, encoding: String.Encoding.ascii.rawValue)!
                    print(theString)
                }
                let newJSONDecoder = JSONDecoder()
                let weatherObject = try newJSONDecoder.decode(WeatherObj.self, from:data!)
                let dailyObject = weatherObject.daily
                let dataArray = dailyObject.data
                //LOOP THROUGH dataArray and get the required info
                for val in dataArray {
                    print("=======")
                    print(val.time)
                    print(val.summary)
                    print(val.icon)
                    print("=======")
                }
            } catch {
                print("error while parsing:\(error.localizedDescription)")
            }


        }

You can create the struct like this

struct WeatherObject: Codable {
  let latitude: Double
  let longitude: Double
  let timezone: String
  let daily: Daily
}

struct Daily: Codable {
    let summary: String 
    let icon: String
    let data: [Datum]
}

struct Datum: Codable {
    let time: Int
    let summary: String
    let icon: String
    let sunriseTime: Int
    let sunsetTime: Int
    let moonPhase: Double
}

Then you can parse it and get the required informations

do {
    let newJSONDecoder = JSONDecoder()
    let weatherObject = try newJSONDecoder.decode(WeatherObject.self, from: jsonData)
    let dailyObject = weatherObject.daily
    let dataArray = dailyObject.data
    //LOOP THROUGH dataArray and get the required info
    for val in dataArray {
        print("=======")
        print(val.time)
        print(val.summary)
        print(val.icon)
        print("=======")
    }
} catch {
    print("error while parsing:\(error.localizedDescription)")
}

Hope it helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM