How to create the model class for the following JSON data and parse it?

PRADIP KUMAR picture PRADIP KUMAR · Jul 27, 2016 · Viewed 34.1k times · Source

My JSON data

{
 "addon_items" : [
                     {
                      "aname" : "",
                      "id" : "2588",
                      "name" : "Plain Nan",
                      "order" : "1",
                      "aid" : "259",
                      "Sub_Add_Items" : "",
                      "icon" : "",
                      "status" : "1",
                      "next" : "0",
                      "price" : "0.60"
                     },
                     {
                      "aname" : "",
                      "id" : "2589",
                      "name" : "Pitta Bread",
                      "order" : "2",
                      "aid" : "259",
                      "Sub_Add_Items" : "",
                      "icon" : "",
                      "status" : "1",
                      "next" : "0",
                      "price" : "0.00"
                    }

                   ],

 "addon" : {
             "description" : "Please choose your Nan bread",
             "aname" : "",
             "id" : "259",
             "icon" : "",
             "limit" : "1",
             "special_addon" : "",
             "next" : "165"
           }
 }

I created three class models named AddOnResponse, AddOn, AddOnItems like this:

AddOnResponse class model

class AddOnResponse {

var addon: Array<String>?
var addonitems: Array<AnyObject>?

init(addon:Array<String>?,addonitems: Array<AnyObject>?){
    self.addon = addon
    self.addonitems = addonitems
 }
}

AddOn class model

class AddOn {


var id: Int?
var icon: String?
var desc: String?
var limit: Int?
var next: Int?
var aname: String?
var specialaddon: Int?

init(id: Int?,icon: String?,desc: String?,limit: Int?,next: Int?,aname: String?,specialaddon: Int?){

    self.id = id
    self.icon = icon
    self.desc = desc
    self.limit = limit
    self.next = next
    self.aname = aname
    self.specialaddon = specialaddon

  }
 }

AddOnItems class model

class AddOnItems {


var id: Int?
var aid: Int?
var name: String?
var price: Int?
var order: Int?
var status: Int?
var next: Int?
var aname: String?
var subaddItems: Int?
var icon: String?

init(id: Int?,aid: Int?,name: String?,price: Int?,order: Int?,status: Int?,next: Int?,aname: String?,subaddItems: Int?,icon: String?){
    self.id = id
    self.aid = aid
    self.name = name
    self.price = price
    self.order = order
    self.status = status
    self.next = next
    self.aname = aname
    self.subaddItems = subaddItems
    self.icon = icon
   }
 }

Now I am fetching my JSON data using Alamofire but when accepting dat into class model using object I am getting nil value.

    var addonResponses = [AddOnResponse]()

    Alamofire.request(.GET, myAddOnUrl)
        .validate()
        .responseJSON
        {   response in
            switch response.result
            {
            case .Success:
                if let value = response.result.value{
                    let json = JSON(value)
                    print(json)
                    print(json["addon"].arrayValue)


           for(_,content) in json{
               let addOnRes = AddOnResponse(addon:content["addon"].arrayValue,
                               addonitems:content["addon_items"].Arrayobject)

                        print(self.addonResponses.count)
                        print(addOnRes.addon)
                        print(addOnRes.addonitems)
                    }
                }

The addon and addonitems data are coming nil, why?

Answer

nishantdesai picture nishantdesai · Jul 27, 2016

After going through your JSON response, what I see is that you are getting an object which has two nodes(or properties). First- "addon_items" which has as array and for which you have created a class AddOnItems which is correct. Second- "addon": this key over here is reference to a 'Dictionary' rather than to an array.

So to store the response in your AddOnResponse object, try the following code.

Alamofire.request(.GET, myAddOnUrl).validate().reponseJSON { response in
    switch resonse.result {
    case .Success:
       if let value = response.result.value {
           let json = JSON(value)
           let responseDictionary = json.dictionaryValue as? [String: AnyObject]
           let addOnRes = AddOnResponse(addon:responseDictionary["addon"].dictionaryValue, addonitems:responseDictionary["addon_items"].arrayValue)
       }
    case .Failure:
       break
    } 
}

Also make change to your AddOnResponse class

class AddOnResponse {
    var addon: [String: AnyObject]?
    var addonitems: Array<AnyObject>?

    init(addon:[String: AnyObject]?,addonitems: Array<AnyObject>?){
        self.addon = addon
        self.addonitems = addonitems
    }
}

TL;DR Your JSON response doesn't properly correspond to the model you've made in your app. Double check the "addon" key of your json response which has a dictionary object to it and NOT AN ARRAY and accordingly make your model classes.

Edit: Rectifying the mistake to point the casting error. What I would now suggest is that pass the JSON object for `add_on' key. In the AddOn class change the initialiser so that it takes a JSON object. Then initialising them using. AddOn Class Initialiser

init(json: JSON) {
    id = json["id"].intValue
    name = json["name"].stringValue
    // and so on
}

Similarly do the same for AddOnItems. And in the AddOnResponse initialiser iterate in a loop the JSON object for AddOnItems. Initialise it and append to the addOnItems array property. Sorry cannot write the code for it right now. Got a time constraint.