想要查看JSON元数据 [英] Want to view json metadata

查看:80
本文介绍了想要查看JSON元数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用适用于iOS的Alpha Vantage API构建显示货币汇率的应用.我已经构建了函数,但是无法弄清楚如何访问确切的json值,即"5. Exchange Rate".

I am trying to build an app that displays Currency exchange rates using the Alpha Vantage API for iOS. I have built the functions but can't figure out how to access the exact json value which is "5. Exchange Rate".

以下是一些代码和json数据,可帮助您更好地进行解释:

Here is some of the code and the json data to help explain better:

内置的URL:

func USDtoEUR(_ completionHandler: @escaping (_ success: Bool, _ quotes: [String:AnyObject]?, _ error: String?) -> Void) {

    let urlString = "https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency=USD&to_currency=EUR&apikey=NP3M8LL62YJDO0YX"
        let session = URLSession.shared
        let url = URL(string: urlString)!

        let request = URLRequest(url: url)
        let task = session.dataTask(with: request, completionHandler: { data, response, error in
            if error != nil {
                completionHandler(false, nil, error!.localizedDescription)
            }
            else {
                do {
                    let result = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as! NSDictionary
                    if let dictionary = result["Realtime Currency Exchange Rate"] as? [String:AnyObject]! {
                        completionHandler(true, dictionary, nil)
                    }
                    else {
                        completionHandler(false, nil, nil)
                    }
                } catch {
                    completionHandler(false, nil, "Unable to process retrieved data.")
                }
            }

        })
        task.resume()

    }

视图控制器中的行情

func usdQUotesRequest() {

  USDClient().USDtoEUR() { success, newQuote, error in

    if success {
        self.usdtoeurquote = newQuote
        DispatchQueue.main.async {
            self.stopActivityIndicator()
            self.Refresh.isEnabled = true
        }

    } else {
        DispatchQueue.main.async {
            self.displayAlert("Unable to Retrieve Latest Conversion Rates", message: "\(error!)")
            self.stopActivityIndicator()
            self.Refresh.isEnabled = true

        }
    }
}

//触摸"USD"按钮后显示的报价:

// The Quotes being showing after touching the USD button:

@IBAction func usdConversions(_ sender: Any) {

    self.displayAlert("Alert!", message: "USD Selected")

    let usdVal = (outputCurrency1.text! as NSString).floatValue

    let euroValue = usdVal * (usdtoeurquote["5. Exchange Rate"] as! Float)
    outputCurrency2.text = String(format: "%.2f", euroValue)

    let gbpVal = usdVal * (usdtogbpquote["5. Exchange Rate"] as! Float)
    outputCurrency3.text = String(format: "%.2f", gbpVal)

    let cnyVal = usdVal * (usdtocnyquote["5. Exchange Rate"] as! Float)
    outputCurrency2.text = String(format: "%.2f", cnyVal)

    let cadVal = usdVal * (usdtocadquote["5. Exchange Rate"] as! Float)
    outputCurrency2.text = String(format: "%.2f", cadVal)

    let inrVal = usdVal * (usdtoinrquote["5. Exchange Rate"] as! Float)
    outputCurrency2.text = String(format: "%.2f", inrVal)

    let sekVal = usdVal * (usdtosekquote["5. Exchange Rate"] as! Float)
    outputCurrency2.text = String(format: "%.2f", sekVal)

    let rubVal = usdVal * (usdtorubquote["5. Exchange Rate"] as! Float)
    outputCurrency2.text = String(format: "%.2f", rubVal)

    let nzdVal = usdVal * (usdtonzdquote["5. Exchange Rate"] as! Float)
    outputCurrency2.text = String(format: "%.2f", nzdVal)

}

原始JSON数据:网页上的json数据

推荐答案

主要错误是键5. Exchange Rate的值是String而不是Float,并且在强行打开包装时,代码可靠地崩溃了.

The main error is that the value for key 5. Exchange Rate is String not Float and the code crashes reliably when being force unwrapped.

在Swift 4中,Decodable协议比字典方便得多.

In Swift 4 the Decodable protocol is much more convenient than a dictionary.

创建两个结构. ExchangeRate结构包含一个计算后的属性floatRate以返回Float

Create two structs. The ExchangeRate struct contains a computed property floatRate to return the Float value

struct Root : Decodable {
    let exchangeRate : ExchangeRate
    private enum  CodingKeys: String, CodingKey { case exchangeRate = "Realtime Currency Exchange Rate" }
}

struct ExchangeRate : Decodable {

    let fromCode, fromName, toCode, toName, rate : String
    let lastRefreshed, timeZone : String

    private enum  CodingKeys: String, CodingKey {
        case fromCode = "1. From_Currency Code"
        case fromName = "2. From_Currency Name"
        case toCode = "3. To_Currency Code"
        case toName = "4. To_Currency Name"
        case rate = "5. Exchange Rate"
        case lastRefreshed = "6. Last Refreshed"
        case timeZone = "7. Time Zone"
    }

    var floatRate : Float {
        return Float(rate) ?? 0.0
    }
}

然后通过将 from 传递给货币作为参数,使下载功能更加通用.此版本使用JSONDecoder并返回ExchangeRate实例或Error

Then make the download function more versatile by passing from and to currency as parameters. This version uses the JSONDecoder and returns either the ExchangeRate instance or the Error

func downloadRate(from: String, to: String, completionHandler: @escaping (ExchangeRate?, Error?) -> Void) {

    let urlString = "https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency=\(from)&to_currency=\(to)&apikey=NP3M8LL62YJDO0YX"
    let task = URLSession.shared.dataTask(with: URL(string: urlString)!, completionHandler: { data, response, error in
        if error != nil {
            completionHandler(nil, error!)
        } else {
            do {
                let result = try JSONDecoder().decode(Root.self, from: data!)
                completionHandler(result.exchangeRate, nil)
            } catch {
                completionHandler(nil, error)
            }
        }
    })
    task.resume()
}

并使用它

func usdQUotesRequest() {

  USDClient().downloadRate(from:"USD", to: "EUR") { exchangeRate, error in

    if let exchangeRate = exchangeRate {
        self.usdtoeurquote = exchangeRate.floatRate
        DispatchQueue.main.async {
            self.stopActivityIndicator()
            self.Refresh.isEnabled = true
        }
    } else {
        DispatchQueue.main.async {
            self.displayAlert("Unable to Retrieve Latest Conversion Rates", message: "\(error!)")
            self.stopActivityIndicator()
            self.Refresh.isEnabled = true
        }
    }
}

这篇关于想要查看JSON元数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆