Galen Smith
Galen Smith

Reputation: 387

Initialization and Storage Error of API Data

I have an exchange rate API initialization / storage problem. I read in some currency exchange rates and would like to store the data temporally in moneyRates then move the data to rateArray as ordered data. I am getting the error "No exact matches in call to initializer". The error is occurring at the line that begins "let result = try JSONSerialization...". I am also seeing a message in the sidebar (Xcode gray !) "/Foundation.Data:29:23: Candidate requires that the types 'MoneyRates' and 'UInt8' be equivalent (requirement specified as 'S.Element' == 'UInt8')". I'm guessing that I need to initialize moneyRates with some kind of format info.

I would like some explanation of the moneyRates error and how to resolve it. I'm not concerned with rateArray at this point. Thanks for your assistance.

struct MoneyRates {
    let date: String
    let base: String
    let rates: [String: Double]
}

class CurrencyRates: ObservableObject{
    
    @Published var moneyRates: [MoneyRates]
    @Published var rateArray = [Double] ()
    
    init() {
        if UserDefaults.standard.array(forKey: "rates") != nil {
            rateArray = UserDefaults.standard.array(forKey: "rates") as! [Double]
            
        } else {
            rateArray = [Double] (repeating: 0.0, count: 170)
            UserDefaults.standard.set(self.rateArray, forKey: "rates")
        }
    }
    
    // retrieve exchange rates for all 150+ countries from internet and save to rateArray
    func updateRates(baseCur: String) {
                 
        let baseUrl = "https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest/currencies/"
        let requestType = ".json"
        
        guard let url = URL(string: baseUrl + baseCur + requestType) else {
            print("Invalid URL")
            return
        }
        let request = URLRequest(url: url)
        
        URLSession.shared.dataTask(with: request) { data, response, error in
            
            if let data = data {
                do {
                let result = try JSONSerialization.jsonObject(with: Data(moneyRates)) as! [String:Any] // <-- error is occurring here
                    
                    var keys = Array(arrayLiteral: result.keys)
                    if let dateIndex = keys.firstIndex(of: "date"),
                       let date = result[keys[dateIndex]] as? String, keys.count == 2 {
                        keys.remove(at: dateIndex)
                        let base = keys.first!
                        let rates = MoneyRates(date: date, base: base, rates: result[base] as! [String:Double])
                        print(rates)
                    }
                } catch {
                    print(error)
                }
            }
            
        }.resume()
    }
}

Upvotes: 0

Views: 76

Answers (1)

jnpdx
jnpdx

Reputation: 52397

If you're trying to decode the result that you get from the URLSession, then instead of passing Data(moneyRates) to decode, you should be passing data from the dataTask closure:

let result = try JSONSerialization.jsonObject(with: data) as! [String:Any]

Upvotes: 1

Related Questions