How do you handle plurals and word order in localised strings?

2.6.4 · L2 · Interview

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… →