Parse json in Swift, AnyObject type Parse json in Swift, AnyObject type swift swift

Parse json in Swift, AnyObject type


This works fine for me in the playground and in the terminal using env xcrun swift

UPDATED FOR SWIFT 4 AND CODABLE

Here is a Swift 4 example using the Codable protocol.

var jsonStr = "{\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],}"struct Weather: Codable {    let id: Int    let main: String    let description: String    let icon: String}struct Result: Codable {    let weather: [Weather]}do {    let weather = try JSONDecoder().decode(Result.self, from: jsonStr.data(using: .utf8)!)    print(weather)}catch {    print(error)}

UPDATED FOR SWIFT 3.0

I have updated the code for Swift 3 and also showed how to wrap the parsed JSON into objects. Thanks for all the up votes!

import Foundationstruct Weather {    let id: Int    let main: String    let description: String    let icon: String}extension Weather {    init?(json: [String: Any]) {        guard            let id = json["id"] as? Int,            let main = json["main"] as? String,            let description = json["description"] as? String,            let icon = json["icon"] as? String        else { return nil }        self.id = id        self.main = main        self.description = description        self.icon = icon    }}var jsonStr = "{\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],}"enum JSONParseError: Error {    case notADictionary    case missingWeatherObjects}var data = jsonStr.data(using: String.Encoding.ascii, allowLossyConversion: false)do {    var json = try JSONSerialization.jsonObject(with: data!, options: [])    guard let dict = json as? [String: Any] else { throw JSONParseError.notADictionary }    guard let weatherJSON = dict["weather"] as? [[String: Any]] else { throw JSONParseError.missingWeatherObjects }    let weather = weatherJSON.flatMap(Weather.init)    print(weather)}catch {    print(error)}

-- Previous Answer --

import Foundationvar jsonStr = "{\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],}"var data = jsonStr.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)var localError: NSError?var json: AnyObject! = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: &localError)if let dict = json as? [String: AnyObject] {    if let weather = dict["weather"] as? [AnyObject] {        for dict2 in weather {            let id = dict2["id"]            let main = dict2["main"]            let description = dict2["description"]            println(id)            println(main)            println(description)        }    }}

Since I'm still getting up-votes for this answer, I figured I would revisit it for Swift 2.0:

import Foundationvar jsonStr = "{\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],}"var data = jsonStr.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)do {    var json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)    if let dict = json as? [String: AnyObject] {        if let weather = dict["weather"] as? [AnyObject] {            for dict2 in weather {                let id = dict2["id"] as? Int                let main = dict2["main"] as? String                let description = dict2["description"] as? String                print(id)                print(main)                print(description)            }        }    }}catch {    print(error)}

The biggest difference is that the variable json is no longer an optional type and the do/try/catch syntax. I also went ahead and typed id, main, and description.


Try:

With it you can go like this:

let obj:[String:AnyObject] = [    "array": [JSON.null, false, 0, "", [], [:]],    "object":[        "null":   JSON.null,        "bool":   true,        "int":    42,        "double": 3.141592653589793,        "string": "a α\t\n𪚲",        "array":  [],        "object": [:]    ],    "url":"http://blog.livedoor.com/dankogai/"]let json = JSON(obj)json.toString()json["object"]["null"].asNull       // NSNull()json["object"]["bool"].asBool       // truejson["object"]["int"].asInt         // 42json["object"]["double"].asDouble   // 3.141592653589793json["object"]["string"].asString   // "a α\t弾\n𪚲"json["array"][0].asNull             // NSNull()json["array"][1].asBool             // falsejson["array"][2].asInt              // 0json["array"][3].asString           // ""


Using my library (https://github.com/isair/JSONHelper) you can do this with your json variable of type AnyObject:

var weathers = [Weather]() // If deserialization fails, JSONHelper just keeps the old value in a non-optional variable. This lets you assign default values like this.if let jsonDictionary = json as? JSONDictionary { // JSONDictionary is an alias for [String: AnyObject]  weathers <-- jsonDictionary["weather"]}

Had your array not been under the key "weather", your code would have been just this:

var weathers = [Weather]()weathers <-- json

Or if you have a json string in your hands you can just pass it as well, instead of creating a JSON dictionary from the string first. The only setup you need to do is writing a Weather class or struct:

struct Weather: Deserializable {  var id: String?  var name: String?  var description: String?  var icon: String?  init(data: [String: AnyObject]) {    id <-- data["id"]    name <-- data["name"]    description <-- data["description"]    icon <-- data["icon"]  }}