简体   繁体   中英

How to make model class for following JSON response in swift iOS

Hi i am beginner for swift ios and my requirement is have to display Json response to table list i got response from web-services and response seems like below

MY requirement is how to map that model classes to Array and how to display them in tableList can some one help me please

JsonResponse:-

[{
  "_id" : "5470def9e0c0be27780121d7",
  "imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/api-static\/clubs\/5470def9e0c0be27780121d7_180.png",
  "name" : "Mondo",
  "hasVip" : false,
  "location" : {
    "city" : "Madrid"
  }
}, {
  "_id" : "540b2ff281b30f3504a1c72f",
  "imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/api-static\/clubs\/540b2ff281b30f3504a1c72f_180.png",
  "name" : "Teatro Kapital",
  "hasVippler" : false,
  "location" : {
    "address" : "Atocha, 125",
    "city" : "Madrid"
  }
}, {
  "_id" : "540cd44581b30f3504a1c73b",
  "imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/api-static\/clubs\/540cd44581b30f3504a1c73b_180.png",
  "name" : "Charada",
  "hasVippler" : false,
  "location" : {
    "address" : "La Bola, 13",
    "city" : "Madrid"
  }
}]

mapping:

Club:-

class Club { 

    var id: String = ""
    var name: String = ""
    var imageUrl: String = ""
    var hasVip: Bool = false
    var desc: String = ""
    var location: [Location] = []

}

Location:-

class Location {

    var country: String = ""
    var city: String = ""
    var address: String = ""
    var zip: String = ""
    var underground: [String] = []

}

NSURlSession code:-

class BackGroundPostCall: NSObject {

    var delegate:PostProtocol?

    func callPostService(url:String,params:NSDictionary){

        print("url is===>\(url)")

        let request = NSMutableURLRequest(URL: NSURL(string:url)!)

        let session = NSURLSession.sharedSession()
        request.HTTPMethod = "POST"

        //Note : Add the corresponding "Content-Type" and "Accept" header. In this example I had used the application/json.
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")

        request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(params, options: [])

        let task = session.dataTaskWithRequest(request) { data, response, error in
            guard data != nil else {
                print("no data found: \(error)")
                return
            }

            do {
                if let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSArray {
                    print("Response: \(json)")
                } else {
                    let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)// No error thrown, but not NSDictionary
                    print("Error could not parse JSON: \(jsonStr)")
                }
            } catch let parseError {
                print(parseError)// Log the error thrown by `JSONObjectWithData`
                let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print("Error could not parse JSON: '\(jsonStr)'")
            }
        }

        task.resume()
    }
}

For mapping you can use Alamofire's extension ObjectMapper.

Ex:

[{
"_id" : "5470def9e0c0be27780121d7",
"imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/api-static\/clubs\/5470def9e0c0be27780121d7_180.png",
"name" : "Mondo",
"hasVip" : false,
"location" : {
    "city" : "Madrid"
}
}, {
    "_id" : "540b2ff281b30f3504a1c72f",
    "imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/api-static\/clubs\/540b2ff281b30f3504a1c72f_180.png",
    "name" : "Teatro Kapital",
    "hasVippler" : false,
    "location" : {
        "address" : "Atocha, 125",
        "city" : "Madrid"
    }
}, {
    "_id" : "540cd44581b30f3504a1c73b",
    "imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/api-static\/clubs\/540cd44581b30f3504a1c73b_180.png",
    "name" : "Charada",
    "hasVippler" : false,
    "location" : {
        "address" : "La Bola, 13",
        "city" : "Madrid"
    }
}]

And mapper class:

import ObjectMapper

class Location: Mappable {
    var address: String?
    var city: String?

    required init?(map: Map){

    }

    func mapping(map: Map) {
        address <- map["address"]
        city <- map["city"]
    }
}

class Club: Mappable {
    var id: String?
    var imageUrl: Int?
    var name: String?
    var hasVip: Bool = false
    var location: Location?

    required init?(map: Map){

    }

    func mapping(map: Map) {
        id <- map["_id"]
        imageUrl <- map["imageUrl"]
        name <- map["name"]
        hasVip <- map["hasVippler"]
        location <- map["location"]
    }
}

And this way very flexible and transparent to use.

https://github.com/Alamofire/Alamofire https://github.com/tristanhimmelman/AlamofireObjectMapper

Using example:

Alamofire.request(URL).responseArray { (response: DataResponse<[Club]>) in

    let clubs = response.result.value

    if let clubs = clubs {
        for club in clubs {
            print(club.name)
            print(club.location.city)           
        }
    }
}

You can make model class using this url: http://www.jsoncafe.com/

open this link and put your json in JSON tab and select any Code Template that is you want. and there is you can also add prefix class name and root class name if you want other wise it is optional. and last click on generate button, your json class is ready.!!

Step1: Create your model like below.

class Club { 
        var id: String = ""
        var name: String = ""
        var imageUrl: String = ""
        var hasVip: Bool = false
        var desc: String = ""
        var location = Location()

        init?(dictionary:[String:Any],location: Location) {
            guard let id = dictionary["_id"],
                let name = dictionary["name"],
                let imageUrl = dictionary["imageUrl"],
                let hasVip = dictionary["hasVippler"]
            else {
                return nil
            }
     self.id = id
     self.name = name
     self.imageUrl = imageUrl
     self.hasVip = hasVip
     self.location = location
  }
 }
}
class Location {

    var country: String = ""
    var city: String = ""
    var address: String = ""
    var zip: String = ""

   init?(dictionary:[String:Any]) {
            guard let country = dictionary["country"],
                let city = dictionary["city"],
                let address = dictionary["address"],
                let zip = dictionary["zip"]
            else {
                return nil
            }
     self.country = country
     self.city = city
     self.address = address
     self.zip = zip
  }
 }
}

Step2: Declare your array as below.

var myTargetArray = [Club]()

Step3: Json Parsing.

    do {
            if let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSArray {
                print("Response: \(json)")

            for club in json {
                   if let clubDictionary = club as? NSDictionary { 
                     if let locationDict = clubDictionary["location"] as? NSDictionary{
                         if let location = Location(dictionary: locationDict) {

                           if let clubObj = Club(dictionary: clubDictionary, location:location) {
                            myTargetArray.append(clubObj)
                       }
                   }
                }
            }
        }
            } else {
                let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)// No error thrown, but not NSDictionary
                print("Error could not parse JSON: \(jsonStr)")
            }
        } catch let parseError {
            print(parseError)// Log the error thrown by `JSONObjectWithData`
            let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
            print("Error could not parse JSON: '\(jsonStr)'")
        }

Note: I removed underground array from location model since your json data does not contain it. Finally you can use your target array as your tableview source. Happy coding...

Model class:

class test : Unboxable {
let id : String
let imageURl : String
let name : String
let hasVip : Bool
let city : String

required init(unboxer: Unboxer) throws {
    self.id = unboxer.unbox(key: "id") ?? ""
    self.imageURl = unboxer.unbox(key: "imageUrl") ?? ""
    self.name = unboxer.unbox(key: "name") ?? ""
    self.hasVip = unboxer.unbox(key: "hasVip") ?? false
    self.city = (unboxer.unbox(key: "city") ?? nil)!
}
}

parse json:

if let object = json as? [Any] {
                // json is an array

                var data :[test] = []
                for respObject in object {

                    var dict = respObject as? Dictionary<String,AnyObject>
                    dict?["city"] = dict?["location"]?["city"] as AnyObject
                     let result1: [test] = try unbox(dictionaries: [dict!])
                    data.append(contentsOf: result1)

                }

                print(data)

For more details follow https://github.com/JohnSundell/Unbox

**Api call with model class, swiftyjson and alamofire,Pod install alamofire and swiftyjson libraries, create collection view cell class, Create a class and write the following code **

import UIKit
import Alamofire
import SwiftyJSON
var myResponse : JSON? = nil
var users : [reasonList] = []
class HomeViewController: UIViewController {
override func viewDidLoad() {
    super.viewDidLoad()
 feedbackApi()
}

func feedbackApi(){
    DispatchQueue.main.async {
        let url = URL(string: "--------")
        let urlRequest = URLRequest(url: url!)
        Alamofire.request(urlRequest)
            .responseJSON { response in
                switch response.result{
                case.success(let data):
                    print("dddd :",data)
                    self.myResponse = JSON(data)
                    print(self.myResponse as Any)
                    let a = self.myResponse![0]["reasonList"]
                    print(a)
                    for i in 0..<a.count{
                        let single = reasonList(reasonListJson: a[i])
                        self.users.append(single)

                    }
                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
                case .failure(let error):
                    print("dddd",error)
                }  
        }
    }
}

}

create a model class

import Foundation
import SwiftyJSON

class user{
var deviceId = String()
var deviceName = String()
var deviceLocationId = Int()
var locationName = String()
var welcomeText = String()
var reason=[reasonList]()
init(userJson:JSON)  {
    self.deviceId = userJson["deviceId"].stringValue
     self.deviceName = userJson["deviceName"].stringValue
     self.deviceLocationId = userJson["deviceLocationId"].intValue
     self.locationName = userJson["locationName"].stringValue
     self.welcomeText = userJson["welcomeText"].stringValue
    self.reason = [reasonList(reasonListJson: userJson["reason"])]
}}
class reasonList{
var reason = String()
var id = Int()
init(reasonListJson:JSON) {
    self.reason = reasonListJson["reason"].stringValue
    self.id = reasonListJson["id"].intValue
]}

**create a collection view in view **

import UIKit
import Alamofire
import SwiftyJSON
class ReasonViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource {
override func viewDidLoad() {
    super.viewDidLoad()
    //DelayCall()


    // Do any additional setup after loading the view.
}
func DelayCall() {
    DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { // Change `2.0` to the desired number of seconds.
        _ = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController")as! HomeViewController
        self.navigationController?.popViewController(animated: true)
    }
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return users.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ReasonCollectionViewCell", for: indexPath) as! ReasonCollectionViewCell
    let useee = users[indexPath.row]

    print(useee)
   cell.reasonLabel.text = useee.reason
    return cell
}}

You can make model class using this url: https://www.json4swift.com/

Open this link and paste your JSON and select from below option you want. Click generate, it will generate class files you can download and used it in your project.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM