Localizely logo
  • Home
  • Getting started
  • How it works
  • Pricing
  • FAQ
Sign up

I18n questions · iOS

How do I localize plurals in an iOS app? 

Write the string once with the count interpolated, and let the localization file hold one form per plural category. Do not assemble the sentence from separate "item" and "items" strings in code; languages have different numbers of forms and different rules for which numbers use them.

In code, the call looks the same for both file formats:

let label = String(localized: "\(count) items")   // iOS 15 and later
Text("\(count) items")                             // SwiftUI

With a String Catalog (Xcode 15 and later), build once so the key %lld items appears in Localizable.xcstrings, then Control-click it and choose Vary by Plural. Xcode adds the categories of the source language (One and Other for English) and, for every language you add later, that language's categories: One, Few, Many and Other for Russian; Zero, One, Two, Few, Many and Other for Arabic. Each form is a complete sentence with the %lld placeholder, and the translator fills in every form their language has.

Before String Catalogs, the same data lives in a .stringsdict property list next to Localizable.strings. The top-level key is the format string used in code, and the other category is required:

<?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>%d items</key>
    <dict>
        <key>NSStringLocalizedFormatKey</key>
        <string>%#@items@</string>
        <key>items</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>d</string>
            <key>one</key>
            <string>%d item</string>
            <key>other</key>
            <string>%d items</string>
        </dict>
    </dict>
</dict>
</plist>
let format = NSLocalizedString("%d items", comment: "Number of items in the cart")
let label = String.localizedStringWithFormat(format, count)

If you call String(localized:) or Text with an interpolated Int instead, the key is %lld items, so use that as the .stringsdict key and lld as the value type.

Both formats rely on the CLDR plural rules, which decide that 21 is "one" in Russian but "other" in English, or that 0 has its own form in Arabic. A category that a language does not use is ignored and other is used instead, so translators must fill exactly the categories of their language; they are listed per language at Language plural rules. The file formats are described at Apple .xcstrings and Apple .stringsdict, and a TMS such as Localizely supports the plural forms of both natively.

Published Oct 9, 2026 · Markdown version

Related iOS localization questions:

Apple localization files:

Learn about Apple .xcstrings string catalogs
Localizely logo
About
Free tools
Boring stuff
  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • Compare
Newsletter
Copyrights 2026 © Localizely