NSLocale currency symbol, show before or after amount value

こ雲淡風輕ζ 提交于 2019-12-03 11:37:56

The locale object doesn't seem to provide this information directly, but of course the number formatter must know it. You're not supposed to ask (new-style) number formatters for their format directly, although that'll probably work, and you can then look for the currency symbol, ¤, in the format string.

Possibly better would be to create a CFNumberFormatter, which does explicitly allow you to view its format, and then inspect that string:

// NSLocale and CFLocale are toll-free bridged, so if you have an existing
// NSNumberFormatter, you can get its locale and use that instead.
CFLocaleRef usLocale = CFLocaleCreate(NULL, CFSTR("en_US"));
CFNumberFormatterRef usFormatter = CFNumberFormatterCreate(NULL, usLocale, kCFNumberFormatterCurrencyStyle);
CFLocaleRef frLocale = CFLocaleCreate(NULL, CFSTR("fr_FR"));
CFNumberFormatterRef frFormatter = CFNumberFormatterCreate(NULL, frLocale, kCFNumberFormatterCurrencyStyle);

NSString * usString = (__bridge NSString *)CFNumberFormatterGetFormat(usFormatter);
NSString * frString = (__bridge NSString *)CFNumberFormatterGetFormat(frFormatter);

NSUInteger loc = ([usString rangeOfString:@"¤"]).location;
NSLog(@"Currency marker at beginning for US? %@", (loc == 0) ? @"YES" : @"NO");
loc = ([frString rangeOfString:@"¤"]).location;
NSLog(@"Currency marker at end for FR? %@", (loc == [frString length] - 1) ? @"YES" : @"NO");

You have everything you need in your SKProduct instance. Just use NSNumberFormatter in conjunction and that's it.

NSNumberFormatter *priceFormatter = [[NSNumberFormatter alloc] init];
[priceFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];        

for (SKProduct *product in response.products) {
    [priceFormatter setLocale:product.priceLocale];
    NSLog(@"Price for %@ is: %@",product.localizedTitle,[priceFormatter stringFromNumber:product.price]);
}

Swift 3+

let priceFormatter = NumberFormatter()
priceFormatter.numberStyle = .currency

for product in response.products {
    priceFormatter.locale = product.priceLocale
    let localizedPrice = priceFormatter.string(from: product.price)
    print("Price for \(product.localizedTitle) is: \(localizedPrice)")
}

I use this solution (Swift):

let currencyFormat = CFNumberFormatterGetFormat(CFNumberFormatterCreate(nil, locale, .CurrencyStyle)) as NSString
let positiveNumberFormat = currencyFormat.componentsSeparatedByString(";")[0] as NSString
let currencySymbolLocation = positiveNumberFormat.rangeOfString("¤").location
return (currencySymbolLocation == 0) ? .Before : .After

The accepted answer should be fixed since the CFNumberFormatterGetFormat sometimes (for some locales) returns double value: ¤##,#00.0;-¤##,#00.0 which includes a negative number format. Make sure to parse that string.

My solution for this was to set the decimal style and set the minimum number of significant digits.

static NSNumberFormatter *NumberFormatter;

if (!NumberFormatter) {
    NumberFormatter = [[NSNumberFormatter alloc] init];
    [NumberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
    [NumberFormatter setUsesSignificantDigits:YES];
    [NumberFormatter setMinimumSignificantDigits:2];
}

NSString *formattedNumberString = [NumberFormatter stringFromNumber:@(valueInEuro)];

NSString *stringInEuro = [NSString stringWithFormat:@"€ %@", formattedNumberString];

I have created an extension of SKProduct, putting things where they belong imho.

extension SKProduct
{
    var localizedPrice: String {
        let numberFormatter = NSNumberFormatter()
        numberFormatter.numberStyle = .CurrencyStyle
        numberFormatter.locale = self.priceLocale
        numberFormatter.formatterBehavior = .Behavior10_4
        return numberFormatter.stringFromNumber(self.price)!
    }
}

That way of formatting is, by the way, also exactly what Apple suggests in the In-App Purchase Programming Guide, section Retrieving Product Information.

Swift 3

An extension function on Locale:

extension Locale {
    func IsCurrenySymbolAtStart() -> Bool {
        let currencyFormatter = NumberFormatter()
        currencyFormatter.numberStyle = .currency
        currencyFormatter.locale = self

        let positiveFormat = currencyFormatter.positiveFormat as NSString
        let currencySymbolLocation = positiveFormat.range(of: "¤").location

        return (currencySymbolLocation == 0)
    }
}

Usage:

let displayCurrencySymbolAtStart = NSLocale.current.IsCurrenySymbolAtStart()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!