How do you handle plurals and word order in localised strings?
Predict first
What does this print?
print(String(format: "%2$@ %1$@", "world", "hello"))
- world hello
- hello world
- %2$@ %1$@
Mental model. A plural rule is a language’s own grammar book. The app should look things up in it, not apply English grammar to everyone.
Never write count == 1 ? "item" : "items". Plural rules differ by language: English has two forms (one, other), Russian four, Arabic six. Put plural variants in the string catalogue (Vary by plural) or a .stringsdict, and let the system pick the form for the number and the language.
Word order differs too, so use positional format arguments: "%1$@ gave %2$@ a gift" lets a translator swap the two. String interpolation in String(localized: "\(count) items") becomes a placeholder automatically. Format numbers and dates with locale-aware formatters rather than by hand, and in recent systems automatic grammar agreement (^[\(n) item](inflect: true)) handles simple plurals for supported languages.
The numbers say which argument goes where, so a translator can reorder the sentence without touching code.
Common traps
- Hard-coded “s” for plurals. It is wrong in English edge cases and in most other languages.
- Positional-less formats.
%@ %@cannot be reordered without changing code.
They might follow up with
- What is a
stringsdict? An older plist format for plural and device variations; string catalogs replace it. - How do you pass a number into a sentence? As a format argument or interpolation, so the formatter can localise its digits too.
Related questions
- 2.6.3 How do you localise strings: Localizable.strings, string catalogs, String(localized:)?
- 2.2.6 What is a Locale, and how is it different from the user’s language?
← How do you localise strings: Localizable.strings, string catalogs… How does the app pick its language at runtime, and how is that… →