要查看json元数据吗

要查看json元数据吗,json,swift,xcode,api,alpha-vantage,Json,Swift,Xcode,Api,Alpha Vantage,我正在尝试构建一个应用程序,使用iOS的Alpha Vantage API显示货币汇率。我已经构建了函数,但不知道如何访问确切的json值,即5。汇率 下面是一些代码和json数据,有助于更好地解释: 创建的URL为: func USDtoEUR(_ completionHandler: @escaping (_ success: Bool, _ quotes: [String:AnyObject]?, _ error: String?) -> Void) { let urlSt

我正在尝试构建一个应用程序,使用iOS的Alpha Vantage API显示货币汇率。我已经构建了函数,但不知道如何访问确切的json值,即5。汇率

下面是一些代码和json数据,有助于更好地解释:

创建的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按钮后显示的报价:

@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数据:

主要错误是键5的值。汇率是字符串而不是浮动的,强制展开时代码可靠崩溃

在Swift 4中,可解码协议比字典方便得多

创建两个结构。ExchangeRate结构包含用于返回浮点值的计算属性floatRate

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

并使用它

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
        }
    }
}

首先,Swift 3+中的JSON字典是[String:Any]。请学习阅读JSON。这很简单。例如,双引号中的所有内容都是字符串,没有例外。所以键5的值。汇率是字符串,而不是浮动汇率。此外,我建议使用可解码协议将JSON解析为结构。因此,我无法使用值进行任何计算,我只能下载它?可以,但您必须从字符串创建一个Double或Float,但请不要通过NSString>floatValueOk很好,谢谢,那么,为什么每次我试图下载它找不到可选值的值时,它都会说?jsonserialization是否正确?usdConversions中会出现异常,因为正如前面提到的,汇率是字符串,而不是浮动。不要使用NSDictionary,强制转换为[String:Any],键实时货币汇率的值实际上更具体[String:String]。并省略options参数。在这种情况下,allowFragments是没有意义的。哦,谢谢!但是,在self.usdtoeurquote=exchangeRate.floarRate部分,我遇到了一个错误:无法将“Float”类型的值赋给“[String:Any]”类型。我将usdtoeurquote声明为var usdtoeurquote=[String:Any]。现在怎么了?我的代码用自定义结构替换了字典。如果您对解码的JSON的所有字段感兴趣,请将usdtoeurquote声明为ExchangeRate,否则将结构实例指定为Float,并指定速率。是的,它成功了!谢谢!尽管如此,我还是收到了一条警告:var usdtoeurquote=ExchangeRate.initfromCode:1。From_货币代码,From名称:2。从_货币名称,到代码:3。要输入货币代码,请输入姓名:4。货币名称,汇率:5。汇率:6。上次刷新,时区:7。时区为?从“ExchangeRate”转换为不相关类型“Float”的Float总是失败。不要将ExchangeRate转换为Float,它们是两种完全不同的类型。请准确使用我的代码self.usdtoeurquote=exchangeRate.floatRate。ExchangeRate结构具有计算属性floatRate,该属性返回从解码的速率字符串创建的浮点。
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
        }
    }
}