1

I want Currency symbol from Currency code. for e.g) EUR -> €, USD -> $, SEK -> kr, DKK -> kr

I am using below code to get currency symbol.

func getSymbolForCurrencyCode(code: String) -> String? {
   let locale = NSLocale(localeIdentifier: code)
   return locale.displayName(forKey: NSLocale.Key.currencySymbol, value: code)
}

But it returns SEK for SEK and DKK for DKK, it should return kr. For USD, GBP, EUR its working fine.

What could be the issue?

Gaurav Borole
  • 796
  • 2
  • 13
  • 32
  • Possible duplicate of https://stackoverflow.com/questions/31999748/get-currency-symbols-from-currency-code-with-swift. – Martin R Sep 28 '17 at 11:01
  • Symbol is locale-specific. The result you get is probably correct for the given locale. – Sulthan Sep 28 '17 at 11:04

2 Answers2

5

It works without using NSLocale class (Swift 3/4):

func getSymbolForCurrencyCode(code: String) -> String? {
    let result = Locale.availableIdentifiers.map { Locale(identifier: $0) }.first { $0.currencyCode == code }
    return result?.currencySymbol
}
getSymbolForCurrencyCode(code: "GBP")
Vlad Khambir
  • 4,313
  • 1
  • 17
  • 25
  • `Locale` and `NSLocale` are the same. This is not really "without NSLocale". – Sulthan Sep 28 '17 at 11:05
  • @Sulthan, but as I know, `Locale` is a `struct` and `NSLocale` is a `class`, am I wrong? – Vlad Khambir Sep 28 '17 at 11:08
  • @V.Khambir, you are correct. It's recommended to use Locale while working in Swift. – Rishi Sep 28 '17 at 11:10
  • 3
    This will loop through all available identifiers unnecessarily. You could just get the first occurrence and return the currency code from it. `guard let identifier = Locale.availableIdentifiers.first(where: { Locale(identifier: $0).currencyCode == code }) else { return nil } return Locale(identifier: identifier).currencySymbol` – Leo Dabus Sep 28 '17 at 11:48
  • btw it does work for SEK -> "kr" but it also returns DKK for DKK – Leo Dabus Sep 28 '17 at 11:51
1

I have created two extensions for strings adding cache to optimize the search.

extension String {
    private static let currencyCode = NSCache<NSString, NSString>()

    public var symbolForCurrencyCode: String? {
        if let cached = Self.currencyCode.object(forKey: self as NSString) {
            return cached as String
        }
        let identifiers = Locale.availableIdentifiers
        guard let identifier = identifiers.first(where: { Locale(identifier: $0).currencyCode == self }) else {
            return nil
        }

        guard let symbol = Locale(identifier: identifier).currencySymbol else {
            return nil
        }

        Self.currencyCode.setObject(symbol as NSString, forKey: self as NSString)

        return symbol
    }
}

extension Optional where Wrapped == String {
    public var symbolForCurrencyCode: String? {
        guard let code = self else {
            return nil
        }
        return code.symbolForCurrencyCode
    }
}

"GBP".symbolForCurrencyCode // "£"
"EUR".symbolForCurrencyCode // "€"
"SEK".symbolForCurrencyCode // "kr"
93sauu
  • 3,770
  • 3
  • 27
  • 43