Получить символы валюты из кода валюты с быстрым
Как я могу получить символы валюты для соответствующего кода валюты с помощью Swift (macOS).
Пример:
- EUR = 1,00 евро
- USD = 1,00 доллара США
- CAD = 1,00 доллара США
- GBP = £ 1,00
Мой код:
var formatter = NSNumberFormatter()
formatter.currencySymbol = getSymbol(currencyCode)
formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
let number = NSNumber(double: (amount as NSString).doubleValue)
let amountWithSymbol = formatter.stringFromNumber(number)!
getSymbol(_ currencyCode: String) → String
или.. есть ли лучший способ?
Ответы
Ответ 1
Немного поздно, но это решение, которое я использовал, чтобы получить $ вместо US $ и т.д. Для символа валюты.
/*
* Bear in mind not every currency have a corresponding symbol.
*
* EXAMPLE TABLE
*
* currency code | Country & Currency | Currency Symbol
*
* BGN | Bulgarian lev | лв
* HRK | Croatian Kuna | kn
* CZK | Czech Koruna | Kč
* EUR | EU Euro | €
* USD | US Dollar | $
* GBP | British Pound | £
*/
func getSymbol(forCurrencyCode code: String) -> String? {
let locale = NSLocale(localeIdentifier: code)
return locale.displayNameForKey(NSLocaleCurrencySymbol, value: code)
}
В основном это создает NSLocale
из вашего кода валюты и захватывает атрибут отображения для валюты. В случае, когда результат соответствует коду валюты, например SEK
он создаст новый языковой стандарт страны, удалив последний символ из кода валюты и добавив "_en" к форме SE_en
. Затем он попытается снова получить символ валюты.
Swift 3 и 4
func getSymbol(forCurrencyCode code: String) -> String? {
let locale = NSLocale(localeIdentifier: code)
if locale.displayName(forKey: .currencySymbol, value: code) == code {
let newlocale = NSLocale(localeIdentifier: code.dropLast() + "_en")
return newlocale.displayName(forKey: .currencySymbol, value: code)
}
return locale.displayName(forKey: .currencySymbol, value: code)
}
Ответ 2
Правильный способ сделать это - предоставить фреймворкам информацию для вас.
Вы можете получить эту информацию с помощью метода неясного класса на NSLocale
, который называется localeIdentifierFromComponents()
. Этот метод примет словарь, который определяет различные атрибуты вашей локали, а затем возвращает идентификатор, который вы можете использовать для фактического создания экземпляра NSLocale
. Если у вас есть NSLocale
, вы можете запросить его CurrencySymbol
, например:
let currencyCode = "CAD"
let localeComponents = [NSLocaleCurrencyCode: currencyCode]
let localeIdentifier = NSLocale.localeIdentifierFromComponents(localeComponents)
let locale = NSLocale(localeIdentifier: localeIdentifier)
let currencySymbol = locale.objectForKey(NSLocaleCurrencySymbol) as! String
// currencySymbol is "CA$"
Ответ 3
Ответ может быть запоздалым, но, надеюсь, это поможет прояснить первопричину.
проблема
- Код валюты не означает, что регион и регион
Причина, по которой CAD становится CA $, вероятно, NSLocale
тем, что NSLocale
просматривает первый соответствующий валютный код, а для CAD - соответствующие localeIdentifiers
в порядке NSLocale.availableLocaleIdentifiers
1. Optional("CA$") Optional("CA") iu_CA
2. Optional("$") Optional("CA") fr_CA
3. Optional("$") Optional("CA") en_CA
iu_CA
- Inuktitut, но я не уверен, почему он указан как CA$
, но я надеюсь, что это ясно.
Аналогичным образом в CNY (китайский юань):
1. Optional("CN¥") Optional("CN") en_CN
2. Optional("¥") Optional("CN") yue_CN
3. Optional("¥") Optional("CN") bo_CN
4. Optional("¥") Optional("CN") zh_CN
5. Optional("¥") Optional("CN") ug_CN
6. Optional("¥") Optional("CN") ii_CN
Причина появления CN ¥, когда en_CN, вероятно, связана с тем, что JPY также использует ¥.
В CHF (швейцарский франк) у них нет однобуквенного символа:
1. Optional("CHF") Optional("LI") gsw_LI
2. Optional("CHF") Optional("CH") de_CH
...
9. Optional("CHF") Optional("CH") en_CH
10. Optional("CHF") Optional("CH") it_CH
Решение
Многие приложения меняются, но это те шаги, которые я принял, что я доволен своим приложением:
- Найти подходящих кандидатов локали, используя поиск кодов валют из всех идентификаторов локали
- Выберите самый короткий символ из кандидатов
- Храните символ где-нибудь, чтобы он не приходилось вычислять каждый раз
Реализация
func getSymbolForCurrencyCode(code: String) -> String {
var candidates: [String] = []
let locales: [String] = NSLocale.availableLocaleIdentifiers
for localeID in locales {
guard let symbol = findMatchingSymbol(localeID: localeID, currencyCode: code) else {
continue
}
if symbol.count == 1 {
return symbol
}
candidates.append(symbol)
}
let sorted = sortAscByLength(list: candidates)
if sorted.count < 1 {
return ""
}
return sorted[0]
}
func findMatchingSymbol(localeID: String, currencyCode: String) -> String? {
let locale = Locale(identifier: localeID as String)
guard let code = locale.currencyCode else {
return nil
}
if code != currencyCode {
return nil
}
guard let symbol = locale.currencySymbol else {
return nil
}
return symbol
}
func sortAscByLength(list: [String]) -> [String] {
return list.sorted(by: { $0.count < $1.count })
}
использование
let usd = getSymbolForCurrencyCode(code: "USD")
let jpy = getSymbolForCurrencyCode(code: "JPY")
let cny = getSymbolForCurrencyCode(code: "CNY")
let cad = getSymbolForCurrencyCode(code: "CAD")
let uah = getSymbolForCurrencyCode(code: "UAH")
let krw = getSymbolForCurrencyCode(code: "KRW")
let zar = getSymbolForCurrencyCode(code: "ZAR")
let chf = getSymbolForCurrencyCode(code: "CHF")
let all = [usd, jpy, cny, cad, uah, krw, zar, chf]
(lldb) po all
▿ 8 elements
- 0 : "$"
- 1 : "¥"
- 2 : "¥"
- 3 : "$"
- 4 : "₴"
- 5 : "₩"
- 6 : "R"
- 7 : "CHF"
Проблемы
- Инстинктивно, я вижу, что подход с символом одной буквы может показывать неправильный символ, если для кода валюты имеется более одного символа, но такого случая я не видел.
- Вычисление это каждый раз тяжело поднимается, поэтому, когда пользователь устанавливает свой валютный настрой, разумно хранить вычисленный результат и использовать этот результат при каждом поиске
Ответ 4
Решение несовершенное, которое я обнаружил, чтобы получить $
вместо US$
или CA$
, было попыткой сначала сопоставить текущую локаль пользователя с кодом валюты. Это будет работать в ситуациях, когда вы создаете мобильное приложение, а API отправляет вам код валюты на основе настроек в этой учетной записи пользователя. Для нас дело в том, что 99% пользователей имеют одинаковый код валюты, указанный в их учетной записи на бэкэнд (USD
, CAD
, EUR
и т.д.), Откуда мы получаем информацию, так как они делают в своем мобильном приложении, где мы показываем валюту так, как пользователь ожидал бы ее увидеть (т.е. $50.56
вместо US$ 50.56
).
Objective-C
- (NSLocale *)localeFromCurrencyCode:(NSString *)currencyCode {
NSLocale *locale = [NSLocale currentLocale];
if (![locale.currencyCode isEqualToString:currencyCode]) {
NSDictionary *localeInfo = @{NSLocaleCurrencyCode:currencyCode};
locale = [[NSLocale alloc] initWithLocaleIdentifier:[NSLocale localeIdentifierFromComponents:localeInfo]];
}
return locale;
}
Swift
func locale(from currencyCode: String) -> Locale {
var locale = Locale.current
if (locale.currencyCode != currencyCode) {
let identifier = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.currencyCode.rawValue: currencyCode])
locale = NSLocale(localeIdentifier: identifier) as Locale
}
return locale;
}
Ответ 5
Вы можете попробовать следующее:
let formatter = NSNumberFormatter()
for locale in NSLocale.availableLocaleIdentifiers() {
formatter.locale = NSLocale(localeIdentifier: locale)
print("\(formatter.currencyCode) = \(formatter.currencySymbol)")
}
Ответ 6
SWIFT4
//converting USD to $a and GBP to £
viewDidLoad()
{
print(getSymbolForCurrencyCode(code: "USD")!) // prints $
print(getSymbolForCurrencyCode(code: "GBP")!) //prints £
}
func getSymbolForCurrencyCode(code: String) -> String?
{
let locale = NSLocale(localeIdentifier: code)
return locale.displayName(forKey: NSLocale.Key.currencySymbol, value: code)
}
Ответ 7
Swift 4 Version ответа Pancho, так как теперь String.characters устарели.
Мы можем просто применить dropLast() к String.
func getCurrencySymbol(from currencyCode: String) -> String? {
let locale = NSLocale(localeIdentifier: currencyCode)
if locale.displayName(forKey: .currencySymbol, value: currencyCode) == currencyCode {
let newlocale = NSLocale(localeIdentifier: currencyCode.dropLast() + "_en")
return newlocale.displayName(forKey: .currencySymbol, value: currencyCode)
}
return locale.displayName(forKey: .currencySymbol, value: currencyCode)
}
Ответ 8
Swift 4.2
// Currency Codes
Locale.isoCurrencyCodes
// Validation
let currencyCode = "USD"
let isValid = 0 < Locale.isoCurrencyCodes.filter { $0 == currencyCode }.count