简体   繁体   中英

Parsing JSON with a nested array in Swift 3

I found this question on parsing JSON in Swift 3 to be very helpful, but I noticed my JSON structure had an array for the "weather" key (see red arrow). I was able to parse other parts of the JSON output, but this array caused problems. 控制台快照

Question: Why am I not able to use the [String:Any] pattern that worked on other parts of this JSON data?.

This is my error in the console: Could not cast value of type '__NSSingleObjectArrayI' (0x112e04be0) to 'NSDictionary' (0x112e05108).

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let url = URL(string: "http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=MYAPIKEY")!

        let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
            if error != nil {
                print(error)
            }else {
                if let urlContent = data {
                    do {
                        let parsedData = try JSONSerialization.jsonObject(with: urlContent, options: .allowFragments) as! [String:Any]
                        print(parsedData)
                       let currentCondions = parsedData["main"] as! [String:Any]

                        for (key, value) in currentCondions {
                            print("\(key) - \(value)")
                        }

                        let locationInfo = parsedData["sys"] as! [String:Any]
                        for (key, value) in locationInfo {
                            print("\(key) - \(value)")
                        }

                        let weatherMain = parsedData["weather"] as! [String:Any]
                        print(weatherMain)

                    } catch {
                       print("JSON processessing failed")
                    }//catch closing bracket
                }// if let closing bracket
            }//else closing bracket
        }// task closing bracket
        task.resume()
    }
}

The error makes the issue fairly clear (that, and looking at the output at the start of your question. The value for the "weather" key is not a dictionary. It's an array of dictionary.

So this:

let weatherMain = parsedData["weather"] as! [String:Any]

needs to be:

let weatherMain = parsedData["weather"] as! [[String:Any]]

As a side note, every use of ! in your app is a crash waiting to happen. You should be safely unwrapping and safely casting values that might not actually be what you think. I strongly suggest you spend some quality time reviewing the sections on optionals, type casting, and optional chaining in the The Swift Programming Language book.

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