Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to localize numbers for iPhone app?

In my iPhone app, I need to display object counts which I then localize, since English makes the distinction of singular and plural, I do the following

// pseudocode

if (objectList.count == 1)
{
   NSLog(@"%@", NSLocalizedString(@"1 object", @"display one objects");
}
else
{
  NSLog(@"%@", NSLocalizedString(@"%d objects", @"display multiple objects");
}

This works for English but in many other languages the plural form of a noun is not simply constructed by adding an ‘s’.

As this page explains, there are two things which can differ between languages:

  • The form how plural forms are built differs. This is a problem with languages which have many irregularities. German, for instance, is a drastic case. Though English and German are part of the same language family (Germanic), the almost regular forming of plural noun forms (appending an ‘s’) is hardly found in German.
  • The number of plural forms differ. This is somewhat surprising for those who only have experiences with Romanic and Germanic languages since here the number is the same (there are two).

How should I deal with this in my code?

like image 316
Boon Avatar asked Oct 27 '09 16:10

Boon


2 Answers

NSLocalizedString is going to be reading from a string table in your app bundle. Therefore, the list of languages you need to support is known at compile time. Rather than worry about how to code for every possible language, just support the ones you are supporting.

If your translator comes to you and says that, to support Martian, you need a separate spelling for even and odd numbers, you can adjust your code then, to something like:

if (objectList.count == 1) {
    NSLocalizedString(@"ObjectCount1", @"display one");
} else if (objectList.count % 2 == 0) {
    NSLocalizedString(@"ObjectCountEven", @"display even");
} else if (objectList.count % 2 == 0) {
    NSLocalizedString(@"ObjectCountOdd", @"display odd");
}

en.lproj/Localizable.strings:

ObjectCount1 = "1 object";
ObjectCountEven = "%d objects";
ObjectCountOdd = "%d objects"; // same as ObjectCountEven

mars.lproj/Localizable.strings:

ObjectCount1 = "1 object-o";
ObjectCountEven = "%d object-e";
ObjectCountOdd = "%d object-o"; // same as ObjectCount1

Sorry if this sounds less than ideal, but human languages are messy and irregular, so it's a waste of time to try to find an elegant, unified, common solution for them all. There isn't one.

like image 53
benzado Avatar answered Oct 06 '22 01:10

benzado


I just posted JJPluralForm, an adaptation for Mozilla's PluralForm.

With that, you wouldn't have to worry about doing all the if-else, switch-case code to do localizing in your code, which becomes impossible to maintain as your number of localizations grow.

Something like the example you gave could be handled with:

[[JJPluralForm sharedManager] pluralStringForNumber:numberOfObjects
                                    withPluralForms:NSLocalizedString(@"N_OBJECTS_PLURAL_STRING", @"")
                                    localizeNumeral:YES];

Each Localizable.strings file then localize N_OBJECTS_PLURAL_STRING as a semicolon separated list of plural forms. For English, that would be "%@ object;%@ objects".

Check out the project for more details.

like image 24
junjie Avatar answered Oct 06 '22 01:10

junjie