Find locale currency for iphone programmatically

32,336

Solution 1

In most cases the currency symbol won't be enough. For example, in Germany we write our prices like this: 1,99€ but people in the US use $1.99. There are three differences in the string. The currency symbol, the position of it and the separator.

If you want to do it right you should use a NSNumberFormatter. It takes care of all the differences between currency formats. And it does it much better than you. Because it does it for all currencies, not just for the 4 main currencies you want to support.

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[formatter setLocale:[NSLocale currentLocale]];
NSString *localizedMoneyString = [formatter stringFromNumber:myCurrencyNSNumberObject];

If you want to use this for in app purchase you can't rely on the users current locale, because it is possible to use a US-based account on a device with a DE (german) locale. And the price of your item (actual price is 0,79€ in Germany) would show as 0,99€ (because it costs $0.99 in the US). This would be wrong. You get a localized price already from the app store, there is no need to do calculations on your own.
And you get a price and a priceLocale for each of your SKProducts.

You would get the correct formatted currency string like this:

SKProduct *product = [self.products objectAtIndex:indexPath.row];
NSNumberFormatter *formatter = [[[NSNumberFormatter alloc] init] autorelease];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[formatter setLocale:product.priceLocale];
currencyString = [formatter stringFromNumber:product.price];

EDIT: since you specifically asked for the currency code.

You can get it with NSString *currencyCode = [formatter currencyCode]; This will give you the currency code according to ISO 4217. AUD, USD, EUR and so on.

Solution 2

I used these keys to extract currency symbols/codes from locales

NSLocale *theLocale = [NSLocale currentLocale];
NSString *symbol = [theLocale objectForKey:NSLocaleCurrencySymbol];
NSString *code = [theLocale objectForKey:NSLocaleCurrencyCode];

Solution 3

I used below code in my app to retrieve local curreny sign and find the delimiters. I will help you,

NSDecimalNumber *amount = [NSDecimalNumber decimalNumberWithString:@"50.00"];
NSNumberFormatter *currencyFormat = [[NSNumberFormatter alloc] init];
NSLocale *locale = [NSLocale currentLocale];
[currencyFormat setNumberStyle:NSNumberFormatterCurrencyStyle];
[currencyFormat setLocale:locale];
NSLog(@"Amount with symbol: %@", [currencyFormat stringFromNumber:amount]);//Eg: $50.00
NSLog(@"Current Locale : %@", [locale localeIdentifier]);//Eg: en_US

Thanks.

Solution 4

create macro first then use it
#define CURRENCY_SYMBOL [[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol]

NSLog(@"%@ %.2f",CURRENCY_SYMBOL,25.50);

Solution 5

Matthias Bauch answer in swift:

var formatter = NSNumberFormatter()
    formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
    formatter.locale = product!.priceLocale
var currencyString = "\(formatter.stringFromNumber(product!.price)!)"
Share:
32,336
vodkhang
Author by

vodkhang

I am interested in quite a range of things from hard core like database system, intelligent to mobile and Human Usability @vodkhang My blog

Updated on July 09, 2022

Comments

  • vodkhang
    vodkhang almost 2 years

    I want to find out the currency locale on user's iphone programmatically. That means, if user is in US Store, the currency locale should be USD, for Australia, it should be AUD. My purpose of this task is to try to convert the item price listed on our app to be nearly match with the price that AppStore ask.

    For example, if we sell a video 3 usd, and an Australian wants to buy it, then I should show 2.8 AUD in my app screen. It will reduce the calculation in the user over the real price in his country. Does anybody know how to do it?

  • keen
    keen almost 11 years
    even if i am in india, it shows me $50 and en_Us. why is this ?
  • keen
    keen almost 11 years
    I tried your first solution. It displays USD instead of INR(india). i don't understand, why?
  • danimal
    danimal over 10 years
    Just a note to watch out for with this answer. Apple has added a Free Tier to IAP. If you use this you will get, for a USD currency locale, $0.00. Be sure to check the product.price for being 0 and handle that accordingly if you want it to say "Free" instead.
  • yano
    yano over 10 years
    ISO 4217 tip is very useful!
  • Dalibor Filus
    Dalibor Filus over 9 years
    [NSLocale currentLocale] returns locale according to system settings? Like: I have locale set to English (America), thus it returns USD?
  • gaussblurinc
    gaussblurinc over 8 years
    use macro for such a simple task? really? messy code from the start?
  • arbel03
    arbel03 over 8 years
    You don't need to add the (formatter.currencyCode) before the stringFromNumber
  • User
    User over 8 years
    This works for dollars but shows a (correctly positioned) weird circle for Euros. When I set currencyCode to "EUR" it shows the correct symbol... hm
  • User
    User over 8 years
    Found the reason, it appears when setting a custom lang in the scheme... when run on device without custom lang the euro symbol appears correctly.
  • Big Money
    Big Money about 8 years
    Watch out for precision loss, NSNumberFormatter will silently strip down NSDecimalNumbers into doubles. Any ideas to get around this?
  • Big Money
    Big Money about 8 years
    This will cause precision loss with decimals larger than doubles
  • rvalue
    rvalue almost 8 years
    @BigMoney indeed if the app handles amounts bigger than what can be formatted from a double.
  • Mohit Singh
    Mohit Singh over 7 years
    Thank you so much for ISO 4217 Currency Code thing - works perfectly!
  • Amin Negm-Awad
    Amin Negm-Awad almost 7 years
    @BigMoney generatesDecimalNumbers (NSNumberFormatter) doesn't work?
  • isuru
    isuru over 5 years
    @gaussblurinc creating macro is a good use of programming. It reduces the messy of the code.