by Lin Junjie (@jjlin)
In English, a word can either be singular or plural (e.g. 1 day, 2 days, 10 days). Some languages like Chinese have only one form (eg. 1 天, 2 天, 10 天), while others like Russian have three (1 день, 2 дня, 10 дней).
Mozilla has codified a set of 17 plural rules across all languages. The rules can be found over here: https://developer.mozilla.org/en/Localization_and_Plurals
JJPluralForm is adapted from Mozilla's
PluralForm to handle plural forms in your Objective-C projects.
Certain plural rules have been extended to include additional plural rules. For example, even though Chinese usually have only one plural form, some scenarios call for up to three different plural forms.
For example, the phrase 'Every N months' can be localized in English as 'Every 1 month', 'Every 2 months' and 'Every 6 months'. Or more naturally, it can be localized as 'Monthly', 'Every 2 months' and 'Every 6 months'.
In Chinese, this would be '每月', '每两个月' and '每 6 个月'. A single plural form would result in an unnatural sounding phrase such as '每 2 个月' to a native speaker.
JJPluralForm header file to any implementation file that requires localizing of plural forms.
Pick a suitable rule from
JJPluralForm.h, and add it to the top of each Localizable.strings file.
For example, adding the following:
"JJ_PLURAL_FORM_RULE" = "1";
to the English version of
Localizable.strings file would specify that the English localization file uses plural rule number 1, which has 2 forms: 1) is one, and 2) everything else.
A convenience macro
kJJPluralFormRule is defined in
JJPluralForm.h, which macro can be used to obtain the plural rule as defined in your
Localizable.strings. Since this macro returns a string, you'd need to convert this to an integer with
[kJJPluralFormRule integerValue] when passing the rule to
JJPluralForm 2.0, you can configure
JJPluralForm with a default plural rule with:
[JJPluralForm setPluralRule:[kJJPluralFormRule integerValue]];
This allows you to use the new method
+pluralStringForNumber:withPluralForms: without specifying the plural rule each time you need to localize a string.
To localize a phrase such as 'N day(s)', provide all plural forms in the
Localizable.strings file in the order as listed in
JJPluralForm.h, separated by semicolons:
"N_DAYS_PLURAL_STRING" = "%@ day;%@ days";
To obtain the correct plural form for the 'N day(s)' expression, use either:
[JJPluralForm pluralStringForNumber:N withPluralForms:NSLocalizedString(@"N_DAYS_PLURAL_STRING", @"") usingPluralRule:[kJJPluralFormRule integerValue] localizeNumeral:YES];
N is the qualifying number. If you'd like the numbers in the returned string to be localized in the current region format, pass
YES to localizeNumeral. This primarily affects locales using a different set of numeral symbols such as Arabic.
If you've earlier configured a default plural rule with
+setPluralRule:, you can use the shorter method to obtain the correct plural form without having to specify the plural rule each time:
[JJPluralForm pluralStringForNumber:N withPluralForms:NSLocalizedString(@"N_DAYS_PLURAL_STRING", @"")];
JJPluralForm uses semicolons to separate plural forms. New in 2.0, you can specify a custom separator. For example, if
N_DAYS_PLURAL_STRING is separated by pipe character (
%@ day|%@ days, you can use this method to obtain the correct plural form:
[JJPluralForm pluralStringForNumber:N withPluralForms:NSLocalizedString(@"N_DAYS_PLURAL_STRING", @"") separatedBy:@"|" usingPluralRule:[kJJPluralFormRule integerValue] localizeNumeral:YES];
JJPluralForms initializes and caches an
NSNumberFormatter set to a
NSNumberFormatterNoStyle. Despite the style name, formatting numbers with this formatter has the effect of making numerals appear in the correct script of the region (eg. Eastern Arabic numerals for Arabic users).
New in 2.1, you can provide your own cached number formatter using
+setDefaultNumberFormatter:. This allows you to customize all aspects of how numbers are formatted when they are localized with
JJPluralForm, for instance, by separating groups of numbers (eg. 1,000,000 vs 1000000).
When calling the following method
the number is formatted and localized with the cached number formatter unless it has been disabled with
+setShouldLocalizeNumeral:. When calling the following methods
- pluralStringForNumber:withPluralForms:usingPluralRule:localizeNumeral: - pluralStringForNumber:withPluralForms:separatedBy:usingPluralRule:localizeNumeral:
the number is formatted and localized with the cached number formatter only if
New in 2.1, you can provide an ad-hoc
NSNumberFormatter to format the number for each call of
pluralStringForNumber: using the following method:
The sample code further illustrates the use of this method.
pod 'JJPluralForm', '~> 2.1'
The code can be downloaded at: https://github.com/junjie/JJPluralForm
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
Attribution in your app's About page is appreciated.
Includes JJPluralForm code by Lin Junjie