Social

Recent Board Games

Contact
This form does not yet contain any fields.
    « Possible Blip | Main | Followups »
    Wednesday
    Jul132011

    Quick tip about localizing currency on iOS

    Let's say you have a text field in your iOS app and you want to take currency values in said field. NSNumberFormatter is your friend and can happily turn a string like "$42.23" into the floating point number 42.23. It will also turn the floating point number 42.23 back in "$42.23". Even better with the German locale active it will turn 42.23 into "$42,23 €" and vice-versa (note the comma as well as the euro symbol). Sweet! However, here's a minor glitch. Sweden's currency "symbol" is in fact a string – "kr". While your formatter will turn the float 42.23 into "42,23 kr" it cannot turn "42,23 kr" back into the floating point value. What to do? What I decided to do was strip whitespace and currency symbols from the string before trying to convert the string into a float. Like so:

    NSCharacterSet* costTrimmingCharacters = nil;
    //OK, some settings have currency symbols that can't survive a 2-way trip. For example, Sweden's currency "symbol" is "kr"
    //So what we're going to do is trim whitespace and currency symbols from the string. Also then we don't have to use the currencyFormatter and can
    //simply use the decimalFormatter (since it will strip $ from US locales, for example.)
    NSMutableCharacterSet* tempSet = [NSCharacterSet whitespaceCharacterSet];
    [tempSet addCharactersInString:[[NSLocale autoupdatingCurrentLocale] objectForKey:NSLocaleCurrencySymbol]];
    costTrimmingCharacters = [tempSet copy];
    //Note in a real app you should store costTrimmingCharacters somewhere and only build it the first time you need it.

    NSNumberFormatter* currencyFormatter = [[NSNumberFormatter alloc] init];
    [currencyFormatter setLocale:[NSLocale autoupdatingCurrentLocale];
    [currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
    NSString* aggravatingString = [NSString stringFromString:@"42,23 kr"] NSString* goodString = [aggravatingString stringByTrimmingCharactersInSet:costTrimmingCharacters]; NSNumber* goodValue = [currencyFormatter numberFromString:goodString]


    Full disclosure: I didn't test that exact snippet, it's frankensteined from a few pieces of code out of RoadTrip that would have just obscured the point. So there may be a syntax error somewhere due to a typo but the idea should be clear. Last two little suggestions:
    1. I use a related character set in the field delegate's shouldChangeCharactersInRange: replacementString: method so that I don't even accept illegal characters and that way you can't even enter "kr" unless you're in the Sweden locale.
    2. In the delegate's textFieldDidEndEditing: method once I've converted the string into a float I go right ahead and convert it back into a string and assign it back into the field. That means if they entered 42.23 they'll see a nice $42.23 or 42,23 € or whatever their locale specifies.

    Reader Comments

    There are no comments for this journal entry. To create a new comment, use the form below.

    PostPost a New Comment

    Enter your information below to add a new comment.

    My response is on my own website »
    Author Email (optional):
    Author URL (optional):
    Post:
     
    All HTML will be escaped. Hyperlinks will be created for URLs automatically.