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?

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
PRADIP KUMAR
  • 489
  • 1
  • 9
  • 31
  • Use Gloss rather than Swifty-json , if will be helpful. – Muzahid Jul 27 '16 at 11:56
  • 1
    cause `addon_items` is an array and `addon` is a dictionary – Özgür Ersil Jul 27 '16 at 11:56
  • 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ürErsil – PRADIP KUMAR Jul 27 '16 at 12:15
  • 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.MuzahidulIslam – PRADIP KUMAR Jul 27 '16 at 12:17
  • Yes agreed @iMuzahid, gloss will make the task lot easier although you can use codable too, try different models you can generate here [jsoncafe.com](http://www.jsoncafe.com) – Meghs Dhameliya Feb 06 '18 at 09:22

7 Answers7

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.

nishantdesai
  • 116
  • 1
  • 3
  • when I used this code i get error in this line......let responseDictionary = json.dictionaryValue as? [String: AnyObject] – PRADIP KUMAR Jul 27 '16 at 13:20
  • error is " Cannot convert value of type '[String : JSON]' to type '[String : AnyObject]' in coercion" – PRADIP KUMAR Jul 27 '16 at 13:21
  • 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. – nishantdesai Jul 27 '16 at 13:27
  • still issue. could you able to edit your answer accordingly – PRADIP KUMAR Jul 27 '16 at 13:40
  • I got the AddOnResponse with few modifications as I posted in my answer. Thanks – PRADIP KUMAR Jul 27 '16 at 14:38
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
    }

}
Ved Rauniyar
  • 1,539
  • 14
  • 21
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)

}
Sushil Sharma
  • 2,321
  • 3
  • 29
  • 49
Prashant Ghimire
  • 518
  • 4
  • 20
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)



                }
PRADIP KUMAR
  • 489
  • 1
  • 9
  • 31
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.

Arshad Shaik
  • 1,095
  • 12
  • 18
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"]
   }

}
ajaykoppisetty
  • 364
  • 4
  • 10
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
  }
}
Jan
  • 4,974
  • 3
  • 26
  • 43