Initialize Swift class with AnyObject? by NSJSONSerialization

I am using NSJSONSerialization

in Swift 1.2 to parse some json that is returned from the API response.

var err: NSError?
let opts = NSJSONReadingOptions.AllowFragments
let json: AnyObject? = NSJSONSerialization.JSONObjectWithData(jsonData!, options: opts, error: &err)

      

The parsed json is provided as AnyObject?

. I would like to use this parameter to initialize a class object that can be used as model data in an application.

class Alerts {
    let type: String
    let date: String
    let description: String
    let expires: String
    let message: String

    init(json: AnyObject) {
        if let
        jsonDict = json as? [String: AnyObject],
        alertsArray = jsonDict["alerts"] as? [AnyObject],
        alertsDict = alertsArray[0] as? [String: AnyObject],
        type = alertsDict["type"] as? String,
        date = alertsDict["date"] as? String,
        description = alertsDict["description"] as? String,
        expires = alertsDict["expires"] as? String,
        message = alertsDict["message"] as? String
        {
            self.type = type
            self.date = date
            self.description = description
            self.expires = expires
            self.message = message
        }
        else
        {
            self.type = "err"
            self.date = "err"
            self.description = "err"
            self.expires = "err"
            self.message = "err"
        }
    }
}

// example of creating a data model from the json
let alerts = Alerts(json: json!)
alerts.type
alerts.date
alerts.description
alerts.expires
alerts.message

      

Since it NSJSONSerialization

returns an optional parameter, I have to check for the existence of each value type when fetching the json data. As you can see in the above code, I have used Swift 1.2's improved optional bindings to clean up the method init

. Without the use of third-party libraries, is there anything else I can do for the model class ( enums

, structs

, type aliases

), to make it more readable? Should I use struct

models for the data instead class

? Is it possible to create a custom type using enum

or struct

to represent a json object?

+3


source to share


1 answer


Thus, without using third party libraries, trees if let

are usually the best practice you have shown. To help you later down the road, maybe recreate the object hierarchy in JSON as a Struct model in Swift. Something like:

var json = JSON(JSONData.sharedjson.jsonRaw!)
var mongoIdTest = json["resultset"]["account"]["mongoId"].string

struct Root {
    var timestamp: Int?
    var resultset = ResultSet()

    init() {
        self.timestamp = json["timestamp"].int
        println(json)
    }

}

struct ResultSet {
    var alert: String?

    var account = Account()
    var customer = Customer()

    init() {

    }


}

struct Account {
    var mongoId: String?

    init() {
        mongoId = json["resultset"]["account"]["mongoId"].string
    }
}

struct Locations {

}

struct Customer {
    var account: String?
    var address: String?
    var id: String?
    var loginId: String?
    var mongoId: String?
    var name: String?

    var opco = Opco()

    init() {
        account = json["resultset"]["customer"]["account"].string
        address = json["resultset"]["customer"]["address"].string
        id = json["resultset"]["customer"]["id"].string
        loginId = json["resultset"]["customer"]["loginId"].string
        mongoId = json["resultset"]["customer"]["mongoId"].string
        name = json["resultset"]["customer"]["name"].string
    }

}

struct Opco {
    var id: String?
    var phone: String?
    var cutOffTime: String?
    var name: String?
    var payerId: String?

    init() {
        id = json["resultset"]["customer"]["opco"]["id"].string
        phone = json["resultset"]["customer"]["opco"]["phone"].string
        cutOffTime = json["resultset"]["customer"]["opco"]["cutOffTime"].string
        name = json["resultset"]["customer"]["opco"]["name"].string
        payerId = json["resultset"]["customer"]["opco"]["payerId"].string
    }
}

      

This way you can use autocomplete and dot notation to navigate your hierarchy.

Edit: I have a data structure from an actual project I was working on added to the answer, hopefully this gives a better idea. Be aware that I am using SwiftyJSON to call JSON()

.



Edit 2:

This is the method I found to get JSON information in a Swift dictionary without using any other library. I'm not sure if there is another way to make this easier without using third party libraries.

var urlToRequest = "https://EXAMPLE.com/api/account.login?username=MY_USERNAME&password=Hunter2"

if let json = NSData(contentsOfURL: NSURL(string: urlToRequest)!) {

    // Parse JSON to Dictionary
    var error: NSError?
    let boardsDictionary = NSJSONSerialization.JSONObjectWithData(json, options: NSJSONReadingOptions.MutableContainers, error: &error) as? Dictionary<String, AnyObject>
    fulljson = boardsDictionary

    // Display all keys and values
    println("Keys in User Data:")
    for (key, value) in boardsDictionary! {
        println("\(key)-------\(value)")
    }

    println(fulljson?["resultset"])
}
else {
    println("Test JSON nil: No Connection?")
}

      

This dictionary will be used for your structures.

0


source







All Articles