Decode JSON Key: String

struct Currency: Codable {
    let result: String
    let conversionRates: [String: Double]

    enum CodingKeys: String, CodingKey {
        case result
        case conversionRates = "conversion_rates"
    }
}

There’s no way of getting the string separated from the double is there? in the constant conversionRates?

@ekraus0227

Ed,

What does the sample JSON code look like?

My Apologies :slight_smile: This as you can guess is for a currency converter. While I can do a vague calculation, I was trying to make it as accurate as possible. I grabbed this API from Github Public API list. If there’s a more native version, I’m all ears :slight_smile:

So the conversion rates are a dictionary which means that when you look up a dictionary item you ask it for the currency which is the String and it will return the value which is the associated Double. So for example if you wanted the conversion rate for AUD you would say this:

let currency = "AUD"
if let conversionValue = conversionRates(currency) {
    // Do something with conversionValue
} else {
    print("No conversion rate for \(currency)")
}

The reason that you use an if let is because if the currency you are asking about does not exist then conversionValue will be nil.

In a dictionary if the Key exists then the Value is returned otherwise nil is returned.

There is no point in doing that since the dictionary process is brilliant once you understand how they work

1 Like

Thanks Chris. I’ll need to figure out how to implement this, but I will also definitely refresh myself on dictionaries and how to manipulate them.

So I’ve been trying to google this… a typical json would be simple… name:string… and when reading up on dictionaries, you still get the value from the key. Which I can do just fine… but not when 1 variable is supposed to handle 2 entities

I know it’s parsed right because I can see the data. I just can’t figure out how to use the data that way

What does this mean?

What way?

Can you show some sample code of what you are trying to do? Because it’s very unclear to me based on what you’ve already written.

The code was above, but here it is. My confusion is how to handle the constant, conversionRates. I know things like the constant, result. But for conversion rates… How would I be able to write the string portion and hide the double, for instance… Together wouldn’t I just re-declare it into a string so it’d all work?

struct Currency: Codable {
    let result: String
    let conversionRates: [String: Double]

    enum CodingKeys: String, CodingKey {
        case result
        case conversionRates = "conversion_rates"
    }
}

My fetch request

    // Beginning to get currency
    func fetchStocks() {
        let urlString = "https://v6.exchangerate-api.com/v6/3af64b8ec60e3e731a5c3068/latest/USD"
        let url = URL(string: urlString)
        
        guard url != nil else {
            return
        }
        let session = URLSession.shared
        let dataTask = session.dataTask(with: url!) { data, response, error in
            
            // Check for errors
            if error == nil && data != nil {
                do {
                    // Parse JSON
                    let decoder = JSONDecoder()
                    let currency = try decoder.decode(Currency.self, from: data!)
                    print(currency)
                }
                catch {
                    print("Error in json parsing")
                }
            }
        }
        // Make the API Call
        dataTask.resume()
    }// End of Stocks API

Do you run conversionRates1:String and then conversionRates2:Double ?

Ed,

No, that’s not how they work.

Dictionaries are not necessarily easy to understand. Let that be OK. I found them difficult initially.

They look like they are arrays but they are not. At some point you will have a lightbulb moment and it will fall into place. It’s just a question of someone explaining it in a different way.

Have a look at this link and see if that helps.

1 Like

Thank you for giving me literature instead of the answer :slight_smile: That’s what I needed. Thank you! I feel like I should be farther along than I am :confused: Really bad at the “marathon not sprint” mentality

Whenever you take on information about something new, give yourself time to absorb it rather than moving onto something else that is new. The key is to consolidate what you have learned and even if you can’t remember the exact syntax later on, at least you know where to look it up from sample code to prompt your memory.

I’ve definitely done that to make what I have made. Having snippets or known resources I agree are great to have and know where to find them at.
Then tailor those to what you need.