如何使用JSON解码字典值中的自定义类型?

如何使用JSON解码字典值中的自定义类型?,json,swift,decodable,Json,Swift,Decodable,我的JSON: 我的代码: 在调试控制台中,将打印以下内容: ["PLN": CurrencyConverter.CoinInfo(Name: "X", Value: 19.6678), ...] 这样我就无法获得硬币的名称和价值属性。怎么了 我将执行for循环来检查一个键是否包含某些符号。如果有-我将需要能够访问名称和值 实际上,您不需要for循环。由于coinData是一个字典,您可以使用它的下标以及可选的绑定来实现这一点。例如,要检查键“PLN”

我的JSON:

我的代码:

在调试控制台中,将打印以下内容:

["PLN": CurrencyConverter.CoinInfo(Name: "X", Value: 19.6678), ...]
这样我就无法获得硬币的
名称
价值
属性。怎么了


我将执行for循环来检查一个键是否包含某些符号。如果有-我将需要能够访问名称和值

实际上,您不需要for循环。由于
coinData
是一个字典,您可以使用它的下标以及可选的绑定来实现这一点。例如,要检查键
“PLN”
是否存在,并访问其名称和值:

if let coinInfo = coinData["PLN"] {
    print(coinInfo.Name)
    print(coinInfo.Value)
} else {
    // "PLN" does not exist
}
舷梯

代码


“这样我就无法获得硬币的名称和价值属性。”你可以。您使用了什么代码试图访问它们?代码产生了什么错误?您希望
coinData.Valute
为您提供哪种硬币属性?换句话说,通过使用
coinData.Valute
,您试图访问哪个硬币的哪个属性(
Name
Value
)?我将执行for循环以检查某个键是否包含某些符号。如果有-我需要能够访问
名称
。因此,哪一个并不重要。我尝试了
coinData.values[0]
-“无法将类型为'Int'的值转换为预期的参数类型'Dictionary.Index'。”。我也试过:
coinData.Valute/CoinInfo/Name
-“类型的值'[String:CoinInfo]'没有成员…”真神奇!谢谢!问题是我把它当作一个数组,所以我指的是索引而不是键
func parseJSON(_ data: Data) -> [String: CoinInfo]? {

    let decoder = JSONDecoder()
     do {
        let decodedData = try decoder.decode(CoinData.self, from: data)
        return decodedData.Valute

     } catch {
        delegate?.didFailWithError(error: error)
        return nil
    }
}
["PLN": CurrencyConverter.CoinInfo(Name: "X", Value: 19.6678), ...]
if let coinInfo = coinData["PLN"] {
    print(coinInfo.Name)
    print(coinInfo.Value)
} else {
    // "PLN" does not exist
}
import UIKit
import Alamofire

// MARK: - CoinData
struct CoinData: Codable {
    let date, previousDate: String
    let previousURL: String
    let timestamp: String
    let valute: [String: Valute]

    enum CodingKeys: String, CodingKey {
        case date = "Date"
        case previousDate = "PreviousDate"
        case previousURL = "PreviousURL"
        case timestamp = "Timestamp"
        case valute = "Valute"
    }
}

// MARK: - Valute
struct Valute: Codable {
    let id, numCode, charCode: String
    let nominal: Int
    let name: String
    let value, previous: Double

    enum CodingKeys: String, CodingKey {
        case id = "ID"
        case numCode = "NumCode"
        case charCode = "CharCode"
        case nominal = "Nominal"
        case name = "Name"
        case value = "Value"
        case previous = "Previous"
    }
}

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
    var getCoinData = [CoinData]()
    var coinNameArr = [String]()
    var coinDataArr = [Valute]()

    @IBOutlet weak var tblDataList: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        getData()
    }

    func getData()
    {
        let url = "https://www.cbr-xml-daily.ru/daily_json.js"
                        
        AF.request(url, method: .get, encoding: URLEncoding.default).responseJSON { response in
            let json = response.data
            do{
                let decoder = JSONDecoder()
                self.getCoinData = [try decoder.decode(CoinData.self, from: json!)]
                let response = self.getCoinData[0]
                if response.valute.count != 0 {
                    self.coinNameArr.removeAll()
                    self.coinDataArr.removeAll()
                    for (coinName, coinData) in response.valute {
                        self.coinNameArr.append(coinName)
                        self.coinDataArr.append(coinData)
                    }
                    self.tblDataList.reloadData()
                } else {
                }
            }catch let err{
                print(err)
            }
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return coinDataArr.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
        let cell:coinTblCell = tableView.dequeueReusableCell(withIdentifier: "CellID", for: indexPath as IndexPath) as! coinTblCell
    
        cell.accessoryType = .disclosureIndicator
        cell.tintColor = .black

        let rowData = coinDataArr[indexPath.row]
        cell.lblName.text = rowData.name
        cell.lblValue.text = String(rowData.value)
    
        return cell
    }

}

class coinTblCell: UITableViewCell {
    @IBOutlet weak var lblName: UILabel!
    @IBOutlet weak var lblValue: UILabel!
}