Want to view json metadata

后端 未结 1 1299
旧时难觅i
旧时难觅i 2021-01-26 00:32

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 j

相关标签:
1条回答
  • 2021-01-26 00:57

    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.

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

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

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

    and use it

    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
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题