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

7

7

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?

Elmaelmajian answered 27/7, 2016 at 11:52 Comment(5)
Use Gloss rather than Swifty-json , if will be helpful.Buttock
cause addon_items is an array and addon is a dictionaryGage
ok then tell me the solution ,, hwz the class model should be for 'addon' and 'addon_items' and how to pass it in the modal@ÖzgürErsilElmaelmajian
Thanks but most of the part i have handled using swiftyJson. so I dont want to use another third party..so if any solution regarding this help me out.. @Md.MuzahidulIslamElmaelmajian
Yes agreed @iMuzahid, gloss will make the task lot easier although you can use codable too, try different models you can generate here jsoncafe.comMaffa
L
9

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.

Liverpool answered 27/7, 2016 at 13:4 Comment(5)
when I used this code i get error in this line......let responseDictionary = json.dictionaryValue as? [String: AnyObject]Elmaelmajian
error is " Cannot convert value of type '[String : JSON]' to type '[String : AnyObject]' in coercion"Elmaelmajian
Don't cast it as [String: AnyObject]. That error was there because there are is more nested data. Cast them at the time of passing it to the initialiser. The reason for this that every last node in a JSON object (SwiftJSON) is of type JSON until and unless you cast it to the last descendant.Liverpool
still issue. could you able to edit your answer accordinglyElmaelmajian
I got the AddOnResponse with few modifications as I posted in my answer. ThanksElmaelmajian
T
5
import Foundation
import SwiftyJSON

class UserInfo {

    var mobile : Int?
    var userid : Int?
    var email : String?
    var name : String?

    init() {

    }

    init(json : JSON){
        mobile = json["phone_number"].intValue
        userid = json["id"].intValue
        email = json["email"].stringValue
        name = json["name"].stringValue
    }

}
Trochelminth answered 30/3, 2017 at 18:22 Comment(2)
Can we use struct instead of class ?My
Yes, Struct is the best option and apple recommends it.Trochelminth
R
1

Try this. I have done this using AlamofireObjectMapper. Check AlamofireObjectMapper for more info

import UIKit
import ObjectMapper


class FollowList: Mappable {

    var addonItems : [addonItemsList]?
    required init?(_ map: Map) {
        super.init(map)
    }
    override func mapping(map: Map) {
        super.mapping(map)

        addonItems <- map["addon_items"]
    }
    }
     class addonItemsList : Mappable{
    var aname : String?
    var id : String?
    var name : String?
    var order : Int?
    var aname : Int?

    required init?(_ map: Map) {

    }
    func mapping(map: Map) {

        aname <- map["aname"]
        id <- map["id"]
        order <- map["order"]
        name <- map["name"]
        icon <- map["icon"]

    }

}

       let URL = "https://raw.githubusercontent.com/tristanhimmelman/AlamofireObjectMapper/2ee8f34d21e8febfdefb2b3a403f18a43818d70a/sample_keypath_json"


          Alamofire.request(.GET, URL)..responseArray { (response: Response<[FollowList], NSError>) in { (response: Response< FollowList, NSError>) in
    expectation.fulfill()

    let FollowList = response.result.value
    print(FollowList?. addonItems)

}
Rego answered 27/7, 2016 at 12:6 Comment(0)
E
1

After so many experiments I got the answer. I have to pass the data to objects like this way. i followed @nishantdesai answers and do some modifications..

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

                    let addOnRes = AddOnResponse(addon: json["addon"].object as? [String : AnyObject],
                                                addonitems: json["addon_items"].arrayObject)
                    print(addOnRes.addon)
                    print(addOnRes.addonitems)



                }
Elmaelmajian answered 27/7, 2016 at 14:36 Comment(0)
C
0

Its very simple to create model class, please follow the below procedure.

Create swift class with name "Sample", write the code as below.

Class Sample{
    var id:String?
    var aname:String?
    var name:String?
    var order:String?
    var aid:String?
    var Sub_Add_Items:String?
    var icon:String?
    var status:String?
    var next:String?
    var price:String?
    func update(info: JSON) {
        id = data["id"].string
        aname = data["aname"].string
        name = data["name"].string
        order = data["order"].string
        aid = data["aid"].string
        Sub_Add_Items = data["Sub_Add_Items"].string
        icon = data["icon"].string
        status = data["status"].string
        next = data["next"].string
        price = data["price"].string
    }
}

and also create one more swift class as "Details" code as below,

Class Details{
    var list: [Sample] = [Sample]()
    func addDetails(data: JSON){
        for(_, detailObj) in data {
            let sampleObj = Sample()
            sampleObj.update(detailObj)
            list.append(sampleObj)
        }
    }
}

and in your viewcontroller before viewdidload() method create an object of Details class as

var detailsObj = Details()

After you got the response from alamofire request method, call the method as below:

self.detailsObj.addDetails(data!["addon_items"] as JSON)

Data is nothing but the response that you get from alamofire.

Later you can access the variables as below:

detailsObj.list[0].name

and you can display it.

Catron answered 10/2, 2017 at 13:34 Comment(6)
If possible how to write a model class can u help me bro @Arshad ShaikHouston
just follow the above procedure , i had mentioned very clearly. If you have any doubts i can help out.Catron
I am having a Json like this json-generator.com/api/json/get/cwqUAMjKGa?indent=2 should I need to use two model classes one for children and another for products @Arshad ShaikHouston
and I need to display as shown in image like this i.sstatic.net/d3U1p.pngHouston
if possible help me I am a trainee so I don't know how to do @Arshad ShaikHouston
@VamsiS sorry for late reply, yes of course you have to create two model classes.Catron
B
0

You can use ObjectMapper

class AddOn: Mappable {
   var description: String!
   var aname: String?
   var id: String!
   var icon: String?
   var limit: String?
   var special_addon: String?
   var next: String?

   required init?(map: Map) {

   }

   // Mappable
   func mapping(map: Map) {
      description <- map["description"]
      aname <- map["aname"]
      id <- map["id"]
      icon <- map["icon"]
      limit <- map["limit"]
      special_addon <- map["special_addon"]
      next <- map["next"]
   }
}

class AddOnItems: Mappable {
   var aname: String?
   var id:String!
   var name: String!
   var order: String?
   var Sub_Add_Items: String?
   var status: String!
   var next: String!
   var price: String!

   required init?(map: Map) {

   }
   // Mappable
   func mapping(map: Map) {
      aname <- map["aname"]
      id <- map["id"]
      name <- map["name"]
      order <- map["order"]
      Sub_Add_Items <- map["Sub_Add_Items"]
      status <- map["status"]
      next <- map["next"]
      price <- map["price"]
   }
}

class requirement: Mappable {

   var addOnItems: [AddOnItems]?
   var addOn: AddOn!

   required init?(map: Map) {

   }
   // Mappable
   func mapping(map: Map) {
     addOnItems <- map["addon_items"]
     addOn <- map["addon_items"]
   }

}
Beryl answered 9/11, 2018 at 5:51 Comment(0)
D
0
class Model{

    let name: string?
    let id: string?
    let name: string?
    let order: string?
    let aid: string?
    let Sub_Add_Items: string?
    let icon: string?
    let status: string?
    let next: string?
    let price: string?


  init(data: [string:any]){
    self.name = data["name"] as? string
    self.id = data["id"] as? string
    self.aname = data["aname"] as? string
    self.aid = data["aid"] as? string
    self.Sub_Add_Items = data["Sub_Add_Items"] as? string
    self.icon = data["icon"] as? string
    self.status = data["status"] as? string
    self.next = data["next"] as? string
    self.price = data["price"] as? string
  }
}
Ditch answered 2/8, 2022 at 5:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.