Skip to article

April 11, 2026

Handling Plurals and Variables in iOS and Android Localization

Learn how to correctly handle pluralization, placeholders, and dynamic values using .xcstrings and Android strings.xml to avoid common localization bugs.

Localization bugs often don’t come from missing translations.

They come from plurals and dynamic values.

Examples:

  • "1 messages" instead of "1 message"
  • broken sentence structure in other languages
  • placeholders appearing in the wrong order

These issues are subtle but critical for user experience.


Why Plurals Are Hard

English has simple plural rules:

  • 1 item
  • many items

Other languages are more complex.

Examples:

  • Russian has multiple plural forms
  • Arabic has 6 plural categories
  • Japanese often avoids plurals entirely

Hardcoding plural logic will break in many languages.


Pluralization in iOS

Legacy approach: .stringsdict

Plural rules were historically handled using .stringsdict.

This required:

  • separate files
  • manual structure
  • harder maintenance

Modern approach: .xcstrings

String Catalogs unify localization into a single format and support pluralization natively.

Pluralization is not written inline. Instead, each string can define structured variations.

Simplified .xcstrings representation

{
  "sourceLanguage": "en",
  "strings": {
    "You have %d messages": {
      "localizations": {
        "en": {
          "stringUnit": {
            "variations": {
              "plural": {
                "one": {
                  "stringUnit": {
                    "value": "You have %d message"
                  }
                },
                "other": {
                  "stringUnit": {
                    "value": "You have %d messages"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

The system automatically selects the correct plural form at runtime based on the current locale and provided arguments.

Using plurals in code

You do not manually switch on count.

Instead, define a natural sentence in your String Catalog, for example:

"You have %d messages"

Then pass the value through interpolation so the localization system can apply plural rules.

Swift

let text = String(localized: "You have \(count) messages")

SwiftUI

Text("You have \(count) messages")

In both cases:

  • "You have … messages" is the source string extracted into the String Catalog
  • \(count) is passed as an argument
  • .xcstrings selects the correct plural form automatically

Important: If you don’t pass arguments through interpolation, pluralization will not work and the system will fall back to the base string.


Pluralization in Android

Android uses <plurals> in strings.xml.

Example:

<plurals name="message_count">
    <item quantity="one">You have %d message</item>
    <item quantity="other">You have %d messages</item>
</plurals>

Usage:

resources.getQuantityString(R.plurals.message_count, count, count)

Each language can define its own plural rules.


Handling Variables and Placeholders

Dynamic values introduce additional complexity.

Examples:

  • "Welcome, %@"
  • "You have %d items"

Problems that occur:

  • placeholder order changes across languages
  • missing variables cause runtime issues
  • formatting breaks grammar

Best Practices for Variables

Use positional placeholders

Avoid relying on fixed word order.

Example:

"%1$@ sent you %2$d messages"

This allows translators to reorder arguments safely.


Always provide context

Explain what each variable represents.

Learn how to improve translation clarity:

Translation Comments Guide


Keep formatting consistent

  • %d for integers
  • %@ for strings
  • match placeholder types exactly across languages

Mismatch can lead to crashes.


Cross-Platform Consistency

When supporting iOS and Android:

  • keep keys consistent
  • align plural logic across platforms
  • validate formatting behavior in both systems

This prevents mismatched user experiences.


Common Mistakes to Avoid

Concatenating strings

"Hello " + name

This breaks in many languages.


Hardcoding plural logic

if count == 1 { ... }

Let localization systems handle this.


Using inline plural hacks

"You have %d message(s)"

This is incorrect for localization and breaks in many languages.


Testing Plurals and Variables

Always validate:

  • all plural forms render correctly
  • placeholders are replaced correctly
  • formatting matches language expectations

Use:

  • pseudo-localization
  • real device testing
  • multiple language configurations

Conclusion

Pluralization and variable handling are among the most common sources of localization bugs.

Using structured formats like .xcstrings and Android plurals ensures:

  • correct grammar across languages
  • fewer runtime errors
  • better translation quality

As your app scales globally, getting this right becomes essential.


Related Articles

> Ready to Localize Your App?

Connect your GitHub repository and start reaching users worldwide

One free language to see how it works · no credit card required