如何为以下 json 使用 codable 和 decodable?

how to use codable and decodable for the following json?

我有一个示例 json 文件,我想用模态 classes 来做,但我不确定如何在代码中做到这一点。

{
    "countryCodes": [{
        "country_code": "AF",
        "country_name": "Afghanistan",
        "dialling_code": "+93"
    },
    {
        "country_code": "AL",
        "country_name": "Albania",
        "dialling_code": "+355"
    },
    {
        "country_code": "DZ",
        "country_name": "Algeria",
        "dialling_code": "+213"
    },
    {
        "country_code": "AS",
        "country_name": "American Samoa",
        "dialling_code": "+1"
    }
    ]
}

我的模态class如下

import Foundation
class CountryModal : NSObject, NSCoding{

    var countryCodes : [CountryCode]!


    /**
     * Instantiate the instance using the passed dictionary values to set the properties values
     */
    init(fromDictionary dictionary: [String:Any]){
        countryCodes = [CountryCode]()
        if let countryCodesArray = dictionary["countryCodes"] as? [[String:Any]]{
            for dic in countryCodesArray{
                let value = CountryCode(fromDictionary: dic)
                countryCodes.append(value)
            }
        }
    }

    /**
     * Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
     */
    func toDictionary() -> [String:Any]
    {
        var dictionary = [String:Any]()
        if countryCodes != nil{
            var dictionaryElements = [[String:Any]]()
            for countryCodesElement in countryCodes {
                dictionaryElements.append(countryCodesElement.toDictionary())
            }
            dictionary["countryCodes"] = dictionaryElements
        }
        return dictionary
    }

    /**
     * NSCoding required initializer.
     * Fills the data from the passed decoder
     */
    @objc required init(coder aDecoder: NSCoder)
    {
        countryCodes = aDecoder.decodeObject(forKey: "countryCodes") as? [CountryCode]
    }

    /**
     * NSCoding required method.
     * Encodes mode properties into the decoder
     */
    @objc func encode(with aCoder: NSCoder)
    {
        if countryCodes != nil{
            aCoder.encode(countryCodes, forKey: "countryCodes")
        }
    }
}

import Foundation
class CountryCode : NSObject, NSCoding{

    var countryCode : String!
    var countryName : String!
    var diallingCode : String!


    /**
     * Instantiate the instance using the passed dictionary values to set the properties values
     */
    init(fromDictionary dictionary: [String:Any]){
        countryCode = dictionary["country_code"] as? String
        countryName = dictionary["country_name"] as? String
        diallingCode = dictionary["dialling_code"] as? String
    }

    /**
     * Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
     */
    func toDictionary() -> [String:Any]
    {
        var dictionary = [String:Any]()
        if countryCode != nil{
            dictionary["country_code"] = countryCode
        }
        if countryName != nil{
            dictionary["country_name"] = countryName
        }
        if diallingCode != nil{
            dictionary["dialling_code"] = diallingCode
        }
        return dictionary
    }

    /**
     * NSCoding required initializer.
     * Fills the data from the passed decoder
     */
    @objc required init(coder aDecoder: NSCoder)
    {
        countryCode = aDecoder.decodeObject(forKey: "country_code") as? String
        countryName = aDecoder.decodeObject(forKey: "country_name") as? String
        diallingCode = aDecoder.decodeObject(forKey: "dialling_code") as? String
    }

    /**
     * NSCoding required method.
     * Encodes mode properties into the decoder
     */
    @objc func encode(with aCoder: NSCoder)
    {
        if countryCode != nil{
            aCoder.encode(countryCode, forKey: "country_code")
        }
        if countryName != nil{
            aCoder.encode(countryName, forKey: "country_name")
        }
        if diallingCode != nil{
            aCoder.encode(diallingCode, forKey: "dialling_code")
        }
    }
}

如何使用这些模型来获取 say India +91 代码的值?我是 swift 的新手,所以我对如何使用这些模型一无所知。

我知道的方法是字典的简单方法

   fileprivate func loadNames(Country: String ) {

            //        //var countryCodes : [CountryCode]!
            //        var dict = [Coordinator]?.self
            if let filePath = Bundle.main.path(forResource: "CountryCode", ofType: "json") {
                if let jsonData = NSData(contentsOfFile: filePath) {


                    do {
                        // countryCodes = try? JSONDecoder().decode(CountryCode.self, from: jsonData as Data)
                        var  countryCodes = try JSONSerialization.jsonObject(with: jsonData as Data, options: []) as? [String: Any]
                        //                    let countryCodes = try? JSONDecoder().decode(Welcome.self, from: jsonData as Data)
                        print ("country d ",countryCodes!)

                        let countryArray = countryCodes!["countryCodes"] as? NSArray
                        if countryArray!.count > 0
                        {
                            for countryElement in countryArray!
                            {
                                let dict = countryElement as! NSDictionary

                                if (dict["country_code"] as! String).description == countryCodeLocale
                                {
                                    print("found ",(dict["dialling_code"] as! String ).description)
                                    country_codeText.text = (dict["dialling_code"] as! String ).description
                                    phone_NumberText.text = "99133131602"
                                    return
                                }
                            }
                        }


                    } catch {
                        print(error.localizedDescription)
                    }





                }
            }
        }
     func fetchValues()
        {
            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            let context = appDelegate.persistentContainer.viewContext

            let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Testing")
            request.returnsObjectsAsFaults = false

            do
            {
                let result = try context.fetch(request)
                for data in result as! [NSManagedObject]
                {
                    self.nameArr.append(data.value(forKey: "name") as! String)
                    self.lastNameArr.append(data.value(forKey: "lastname") as! String)
                }
                self.tableView.reloadData()

            } catch {

                print("Failed")
            }
        }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
        {
            return self.nameArr.count
        }
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
        {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? testTVCell
            cell?.nameLbl.text = self.nameArr[indexPath.row]
            cell?.lastNameLbl.text = self.lastNameArr[indexPath.row]
            cell?.deleteBtn.tag = indexPath.row

            return cell!
        }
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
        {
            return UITableView.automaticDimension
        }

        func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
            return true

        }
        @IBAction func deleteAction(_ sender: UIButton) {

    //        self.nameArr.remove(at: sender.tag)
    //        self.lastNameArr.remove(at: sender.tag)
    //        self.tableView.reloadData()

            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            let context = appDelegate.persistentContainer.viewContext

            let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Testing")
            fetchRequest.returnsObjectsAsFaults = false


            let index = sender.tag
            do
            {
                if let result = try? context.fetch(fetchRequest)
                {

                    for object in result as! [NSManagedObject]

                    {
                        print(object.value(forKey: "name") as! String)

                        if ((object).value(forKey: "name") as! String).description == nameArr[index]
                        {
                            print(object.value(forKey: "name") as! String)
                        context.delete(object )
                            self.lastNameArr.remove(at: index)
                            self.nameArr.remove(at: index)
                            DispatchQueue.main.async
                                {
                             self.tableView.reloadData()

                            }
                           break
                        }
                    }
                }
            }
                catch
                {
                    print("error")
                }


            let _ : NSError! = nil
            do {
                try context.save()
                self.tableView.reloadData()
            } catch {
                print("error : \(error)")
            }
        }
        func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
                    if editingStyle == .delete {
                        print("Deleted")
                        let appDelegate = UIApplication.shared.delegate as! AppDelegate
                        let context = appDelegate.persistentContainer.viewContext

                        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Testing")
                        fetchRequest.returnsObjectsAsFaults = false


                        let index = indexPath.row
                        do
                        {
                            if let result = try? context.fetch(fetchRequest)
                            {

                                for object in result as! [NSManagedObject]

                                {
                                    print(object.value(forKey: "name") as! String)

                                    if ((object).value(forKey: "name") as! String).description == nameArr[index]
                                    {
                                        print(object.value(forKey: "name") as! String)
                                        context.delete(object )

                                        DispatchQueue.main.async
                                            {

                                        }
                                    }
                                }
                            }
                        }
                        catch
                        {
                            print("error")
                        }


                        let _ : NSError! = nil
                        do {
                            try context.save()

                        } catch {
                            print("error : \(error)")
                        }

                        self.lastNameArr.remove(at: index)
                        self.nameArr.remove(at: index)
                        self.tableView.deleteRows(at: [indexPath], with: .automatic)
                    }
@IBAction func submitTapped(_ sender: Any)
    {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.persistentContainer.viewContext
        let entity = NSEntityDescription.entity(forEntityName: "Testing", in: context)
        let newUser = NSManagedObject(entity: entity!, insertInto: context)

        newUser.setValue(self.nameTxt.text, forKey: "name")
        newUser.setValue(self.lastNameTxt.text, forKey: "lastname")

        do
        {
            try context.save()
        }
        catch
        {
            print("Failed saving")
        }
    }

    func apiCall()
    {
        let urlString = "https://example.org"
        let url = NSURL(string: urlString)
        let request = NSMutableURLRequest(url: url! as URL)
        activityView.startAnimating()
        self.view.addSubview(activityView)
        request.httpMethod = "GET"

        let task = URLSession.shared.dataTask(with: request as URLRequest) { data,response,error in

            if error != nil
            {
                DispatchQueue.main.async
                    {
                let alert = UIAlertController(title: "Network Connection Lost", message: "Please try again", preferredStyle: .alert)
                let ok = UIAlertAction(title: "OK", style: .cancel, handler: { Void in
                    self.activityView.stopAnimating()
                })
                alert.addAction(ok)
                self.present(alert, animated: true, completion: nil)
                }
               return
            }
            do
                {
                    let result = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as AnyObject
                    print(" JSON : ", result)
                    let a = result as! NSArray
                    let b = a[0] as! NSDictionary
                    print("name ",  (b["Name"] as! String).description)

                    var nameArray = [String]()
                    for element in a
                    {

                        nameArray.append(((element as! NSDictionary)["Name"] as! String).description)
                    }
                    print("nameArray ",  nameArray)
                    DispatchQueue.main.async
                        {
                    self.activityView.stopAnimating()
                            self.activityView.isHidden = true
                    }


            }
            catch
            {
                print("Error -> \(error)")

                DispatchQueue.main.async
                    {
                        self.activityView.stopAnimating()
                        let alert = UIAlertController(title: "Alert?", message: error as? String,preferredStyle: .alert)
                        let ok = UIAlertAction(title: "OK", style: .cancel, handler:  nil)
                        alert.addAction(ok)
                        self.present(alert, animated: true, completion: nil)
                        return
                }
            }
        }
        task.resume()
    }
}


  let indexpath = NSIndexPath(row: sender.tag, section: 0)

        let cell = tableView.cellForRow(at: indexpath as IndexPath) as? testTVCell

        if (self.tableView.isEditing) {
            cell?.deleteBtn.setTitle("Edit", for: .normal)

            self.tableView.setEditing(false, animated: true)
        } else {
            cell?.deleteBtn.setTitle("Done", for: .normal)

            self.tableView.setEditing(true, animated: true)
        }
{

        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let urlString = appDelegate.serverUrl + "queryClassifiedList"
        let url = NSURL(string: urlString)
        let request = NSMutableURLRequest(url: url! as URL)
        let spinner = JHSpinnerView.showDeterminiteSpinnerOnView(self.view)

        spinner.progress = 0.0
        self.view.addSubview(spinner)

        request.httpMethod = "POST"

        request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
        request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")

        var dict : [AnyHashable: Any] = [
            "channel" : appDelegate.channel,
            "device" : appDelegate.deviceId,
            "classifiedtype" : self.classifiedType,
            "startnum" : startNum,
            "endnum" : endNum
        ]

        if UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int != nil && UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int != -1
        {
            let categoryRow = (UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int)!
            dict["categoryid"] = categoryRow
        }

        if UserDefaults.standard.value(forKey: "cityRowFilter") as? Int != nil && UserDefaults.standard.value(forKey: "cityRowFilter") as? Int != -1
        {
            let cityId = (UserDefaults.standard.value(forKey: "cityRowFilter") as? Int)!
            dict["city"] = cityId
        }

        let jsonData: Data? = try? JSONSerialization.data(withJSONObject: dict, options: [])
        request.httpBody = jsonData

let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let urlString = appDelegate.serverUrl + "queryClassifiedList"
        let url = NSURL(string: urlString)
        let request = NSMutableURLRequest(url: url! as URL)
        let spinner = JHSpinnerView.showDeterminiteSpinnerOnView(self.view)

        spinner.progress = 0.0
        self.view.addSubview(spinner)

        request.httpMethod = "POST"

        var bodyData : String!

        bodyData = "channel=" + appDelegate.channel + "&device=" + appDelegate.deviceId + "&Classifiedtype=" + self.classifiedType.description + "&Startnum=" + startNum.description + "&Endnum=" + endNum.description

        if UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int != nil && UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int != -1
        {
            let categoryRow = (UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int)!

            bodyData = bodyData + "&Categoryid=" + categoryRow.description
        }

        if UserDefaults.standard.value(forKey: "cityRowFilter") as? Int != nil && UserDefaults.standard.value(forKey: "cityRowFilter") as? Int != -1
        {
            let cityId = (UserDefaults.standard.value(forKey: "cityRowFilter") as? Int)!

            bodyData = bodyData + "&city=" + cityId.description
        }

        print("bodyData : ", bodyData)

        request.httpBody = bodyData.data(using: String.Encoding.utf8)
}

但我想要模态 class 方法实现。有人可以帮忙吗?

你可以试试

struct Root: Codable {
    let countryCodes: [CountryCode]
}

struct CountryCode: Codable {
    let countryCode, countryName, diallingCode: String

    enum CodingKeys: String, CodingKey {
        case countryCode = "country_code"
        case countryName = "country_name"
        case diallingCode = "dialling_code"
    }
}

let res = try? JSONDecoder().decode(Root.self,from:jsonData)
print(res.countryCodes)

res.countryCodes.forEach {
   if [=11=].countryCode == "DZ" {
     print([=11=].diallingCode)
   }
 }