Pluralizing your localisations

Pluralizing your localisations

Everbody is familiar with how you handle different languages in iOS. Most of the time you have a .strings file with the translations. And in code you call the NSLocalizedString macro.

For example the contents of the English .strings file:

"documents.title" = "Documents";

And we can translate this key in our code like this:

NSLocalizedString(@"documents.title", @"The documents title");

"What happens when you have a text that contains a number which reflects a word that needs to be pluralized?"But what happens when you have a text that contains a number. And this number reflects a word that needs to be pluralized.
For example: "Here are 4 documents". In this case you want to show "Here is 1 document" when only 1 document is available.

How do we handle this kind of localization?What we can to is create two keys in our strings file and choose the correct one depending on the number of documents.

"documents.description.plural" = "Here are %d documents";
"documents.description.singular" = "Here is %d document";

Not so nice if you ask me.But wait, there is a better way to handle this.

1. Create a new .stringsdict file next to your .strings file. Make sure the filename is exactly the same as your localized strings file. For example: Localizable.string matches Localizable.stringsdict.

2. This .stringsdict file should contain a plist like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
	<dict>
		<key>documents.description</key>
		<dict>
			<key>NSStringLocalizedFormatKey</key>
			<string>%#@documents@</string>
			<key>documents</key>
			<dict>
				<key>NSStringFormatSpecTypeKey</key>
				<string>NSStringPluralRuleType</string>
				<key>NSStringFormatValueTypeKey</key>
				<string>lu</string>
				<key>one</key>
				<string>Here are %lu documents</string>
				<key>other</key>
				<string>Here is %lu document</string>
			</dict>
		</dict>
	</dict>
</plist>

3. You can remove the 'documents.description.plural' and 'documents.description.singular' keys from your _.strings_ file.

4. Now fetch the translation from your code, and see how the correct translation is used depending on the number of documents.

[NSString stringWithFormat:NSLocalizedString(@"documents.description", @"Documents description"), [documents count]];

Well this is fairly simple.

When a key is defined in the .stringsdict file, it will be used instead of the one in your .strings file.

- The first key in the file documents.description is your key used in the NSLocalizedString macro. This is the key to a dictionary with the pluralization information.

- The NSStringLocalizedFormatKey key defines a string with some placeholder variables in it. In our case the placeholder variable is documents.

- The documents variable translation is defined in the dictionary belonging to this key. So the dictionary below defines the pluralization rules for the documents placeholder.

<dict>
	<key>NSStringFormatSpecTypeKey</key>
	<string>NSStringPluralRuleType</string>
	<key>NSStringFormatValueTypeKey</key>
	<string>lu</string>
	<key>one</key>
	<string>Here are %lu documents</string>
	<key>other</key>
	<string>Here is %lu document</string>
</dict>

- With the NSStringFormatSpecTypeKey you say you want to do pluralization, and NSStringFormatValueTypeKey specifies the number format.

- After that you only need to define the keys with their matching format string. In most cases you'll use one (for singular) and other (for multiple). But sometimes you want to be more specific and use zero, one, two, few, other and many.More information can be found here, here and here.