swifturlcomponents

Passing a Value into URLComponents


I have an API that returns currency exchange rates. I have been using a hardcoded string for the URL and would like to convert it to URLComponents. With my hardcoded string, I have been using the following code where baseCur is the passed-in base currency 3-digit code ("eur", "usd", "cad", etc):

let sRand = String(".json?rand=\(Int.random(in: 1000..<10000))")
let baseUrl = "https://cdn.sampleCode.net/currency-api@latest/currencies/"

guard let url = URL(string: baseUrl + baseCur + sRand) else {
    return
}

The URL string might look something like this:

https://cdn.sampleCode.net/currency-api@latest/currencies/eur.json?rand=6138

I have had some trouble with cache data being used instead of JSON data, and was told to include a random number on the end of the string.

Below is my attempt to do the same thing with components. The following code works correctly but is using a hardcode baseCur value. What I want to know is how to pass in baseCur ("eur", "usd", "cad", etc) without hardcoding the base currency.

@Observable final class GetRatesModel {
    @MainActor func checkForUpdates(baseCur: String) async throws {
        let rand = Int.random(in: 1000..<10000)
        let sRand = String(rand)
        
        var components = URLComponents()
        components.scheme = "https"
        components.host = "cdn.sampleCode.net"
        components.path = "/currency-api@latest/currencies/eur.json"
        components.queryItems = [.init(name: "rand", value: sRand)]
    
        print(components)
    }
}

Solution

  • I believe you're looking for string interpolation:

    String interpolation is a way to construct a new String value from a mix of constants, variables, literals, and expressions by including their values inside a string literal. You can use string interpolation in both single-line and multiline string literals. Each item that you insert into the string literal is wrapped in a pair of parentheses, prefixed by a backslash (\)

    components.path = "/currency-api@latest/currencies/\(baseCur).json"
    

    (also, I suspect that date/time would be more robust than a random number for forcing the cache to be skipped)