Search code examples
ioslocalizationinternationalizationmessageformatcldr

Explicit Plural string using iOS Stringsdict files


I am getting started learning iOS Stringsdict files and found some existing code on a project which used the following syntax:

<key>zero</key>
<string>You no message.</string>

As per the CLDR, zero is an invalid plural in English and we expect to use explicit plural rules (=0 when using ICU MessageFormat)

I tried to find how to use explicit plural rules in iOS Stringsdict files and could not find any way to achieve this. Can someone confirm if this is supported or not?


Example of solutions (I cannot test them but maybe someone can?)

<key>0</key>
<string>You no message.</string>

Or

<key>=0</key>
<string>You no message.</string>

Extra reference on explicit plural rules part of the CLDR implementation of ICU MessageFormat:

https://formatjs.io/guides/message-syntax/#plural-format

=value This is used to match a specific value regardless of the plural categories of the current locale.


Solution

  • Short Answer

    .stringsdict files have no way to support explicit plural rules (other than a custom Apple implementation of zero which is detailed below)

    Detailed Answer

    Normal CLDR implementation:

    • All rules that are not in the CLDR for a given language will be ignored
    • If using the rule zero, it will use the CLDR values (most languages have 0 as value for zero). This also includes languages like Latvian who have 20, 30, etc. values mapped to zero and also contradicts Apple's own documentation (this behavior was verified):

    If "zero" is present, the value is used for mapping the argument value zero regardless of what CLDR rule specifies for the numeric value.

    Source: Foundation Release Notes for OS X v10.9

    Custom (Apple) CLDR implementation:

    • All languages can use the zero category from the CLDR even if the rule is not defined for this language (reference here)
    • Presumably, they implemented this to facilitate negative forms of sentences which is a common use case (this can even be found in their examples). For example instead of writing:

    You have 0 emails.

    You can write:

    You have no emails.

    • This is a very common use case but is typically not covered using CLDR categories, it is used by using explicit values. For example, in ICU MessageFormat you can use =0 and not zero for negative forms.
      • While this seems convenient, it creates a big problem, what if you want to use negative forms for Latvian using the zero category? You simply can't - basically Apple broke linguistic rules by overwriting the CLDR.

    Complimentary details:

    • There are only two languages in the CLDR where zero does not equal 0:
    • Neither iOS nor macOS is available in the Latvian languages but they support locale settings (keyboard and date formats)
    • This means that there are probably few applications that will support Latvian, unless they have a manual way to change the language inside the application itself (this is a less common scenario for iOS which typically honor the device's settings)

    Conclusion

    Tip #1: If you need to use Latvian, you should probably avoid using zero for negative forms, and use code instead, with strings outside of the stringsdict file

    Tip #2: Make sure that your translation process supports this behavior correctly!