views:

2130

answers:

1

I would like my iPhone app to allow the input, display and storage of currency amounts using the appropriate symbol ($, €, ₤, ¥, etc) for the user.

Would NSNumberFormatter do everything I need? What happens when a user switches their locale and these amounts (dollars, yen, etc.) are stored as NSDecimalNumbers. I assume, to be safe, it's necessary to somehow capture the locale at the time of entry and then the currency symbol and store them in my instance along with the NSDecimalNumber ivar so they can be unwrapped and displayed appropriately down the road should the user changed their locale since the time when the item was created?

Sorry, I have little localization experience so hoping for a couple quick pointers before diving in. Lastly, any insight on how to you handle this kind of input given the limitations of the iPhone's keyboards?

+6  A: 

NSNumberFormatter is definitely the way to go! You can set a NSLocale on the NSNumberFormatter, the formatter will automatically behave according to that locale. The default locale for a number formatter is always the currency for the users selected region format.

NSDecimalNumber *someAmount = [NSDecimalNumber decimalNumberWithString:@"5.00"];

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

NSLog(@"%@", [currencyFormatter stringFromNumber:someAmount]);

This will log the amount '5.00' according to the users default region format. If you want to alter the currency you can set:

[currencyFormatter setLocale:aLocale];
klaaspieter
That's what I thought. I'm curious what happens when the user changes their locale after someAmount has been archived to disk. The iPhone could, quite easily, find itself in another country on a business trip. If the user is comfortable with the local language etc they may change the Locale. What happens when this object is unarchived? Will it display as '$5.00' as was created and intended, or will it display as '¥5' which, obviously, has a significantly different monetary value but is a correctly formatted NSDecimalNumber of '5.00' when the currencyFormatter's locale is Japan.
Meltemi
You can store someAmount formatted or unformatted. If you store it formatted, the amount will always reflect the currency it was made in. If you store it unformatted, the formatter will just format it in the current locale, but will not do any conversion! Thus: '$5.00' will become '¥5'. What I do in my app is store both the unformatted currency and it's locale. This way I am always sure that the currency is formatted in the locale it was made in, but I can also add currency conversion later on.
klaaspieter
just by c/p'ing this code, i get the warning: format not a string literal and no format argumentsCan i not get this?
norskben
@norskben - Try `NSLog(@"%@",[[currencyFormatter stringFromNumber:someAmount] description]);`
Moshe
Excellent code, worked well for me.
Moshe
@norskben - Apple changed the behavior of NSLog without a format argument to throw a warning at some point. My code was written before that point.I corrected the code, it should work without warning now.
klaaspieter