Xcode, Swift: how to add multi-language support in an iOS app and have strings with placeholders and plurals?

10,101

Solution 1

Setup project Localizations, as shown in screenshot the project has English and Russian languages.

enter image description here

1: Create a file named Localizable.strings and add following lines

static_string="Hello world!";
placeholder_string="You have %d new messages.";

2: We define Plurals in a separate file, lets create a file named Localizable.stringsdict and paste following:

<?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">

<!-- FIRST PLURAL STRING -->
<dict>
    <key>plural_string</key>
    <dict>
        <key>NSStringLocalizedFormatKey</key>
        <string>%#@value@</string>
        <key>value</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>d</string>
            <key>one</key>
            <string>You have a new message.</string>
            <key>other</key>
            <string>You have %d new messages.</string>
        </dict>
    </dict>
</dict>

<!-- NEXT PLURAL STRING -->
</plist>

Next, localize Localizable.stringsdict file, see in screenshot, the file is localized for English and Russian languages:

enter image description here

Usage:

NSLocalizedString("static_string", comment: "") // Hello world!

String(format: NSLocalizedString("placeholder_string", comment: ""), 5) // You have 5 new messages.

let plural = NSLocalizedString("plural_string", comment: "")
String(format: plural, 1) // You have a new message.
String(format: plural, 2) // You have 2 new messages.

Plural Rules: In XML code, notice <key>one</key> and <key>other</key>, here you can use zero, one, two, few, many, other depending on the language and your requirements.

Use following link for more information on language specific plural rules: http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html

Also this article will help if you are new to string formatting https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html

Solution 2

This blog explains in great detail what plurals are all about. with code examples for IOS.

in some languages, plurals don't work the same way as they do in English. Some languages don't indicate plurals (such as Japanese), while for others the word will change depending on the quantity (such as Russian).

To make things a bit easier, iOS has categorised the different plural types as follows:

  • Zero. Used to indicate a 0 quantity.
  • One. Used to indicate a quantity of exactly 1.
  • Two. Used to indicate a quantity of exactly 2.
  • Few. Used to indicate a small quantity greater than 2, but this depends on the language.
  • Many. Used to indicate a large number, but this also depends on the language.

Other. Used to indicate every number that isn't covered by the above categories.

Not all languages need all categories specified, since all work differently. At first glance, it would appear that English would require rules for zero, one and many. However, the plural rules for English would be specified with one and other, since all numbers apart from 1 are treated equally.

To specify the plural rules, you need to use a strings dictionary (Localizable.stringsdict) instead of a regular Localizable.strings file. In actual fact, you'll need the .strings file to still be present for the .stringsdict to work, even if it's empty.

In Xcode, create a new Plist file, and name it Localizable.stringsdict. Once populated, the raw data in the Plist will look as follows:

<?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>number_of_days</key>
        <dict>
            <key>NSStringLocalizedFormatKey</key>
            <string>%#@value@</string>
            <key>value</key>
            <dict>
                <key>NSStringFormatSpecTypeKey</key>
                <string>NSStringPluralRuleType</string>
                <key>NSStringFormatValueTypeKey</key>
                <string>d</string>
                <key>one</key>
                <string>%d day remaining</string>
                <key>other</key>
                <string>%d days remaining</string>
            </dict>
        </dict>
    </dict>  
    </plist> 

And this is how to reference the plural in code:

let format = NSLocalizedString("number_of_days", comment: "")
let message = String.localizedStringWithFormat(format, numDays)

Again, credit goes to Quentin

Share:
10,101

Related videos on Youtube

AamirR
Author by

AamirR

Updated on October 21, 2022

Comments

  • AamirR
    AamirR over 1 year

    I need to add multi-language support in an iOS app that is written in Xcode using Swift. I need to localize

    1. Static strings
    2. Strings with placeholders
    3. plurals (quantity-strings)

    Such as below in Android we add named strings and plurals in XML files:

    <string name="static_string">Hello world!</string>
    <string name="placeholder_string">You have %2$d new messages.</string>
    <plurals name="plural_string">
        <item quantity="one">You have a new message.</item>
        <item quantity="other">You have %2$d new messages.</item>
    </plurals>
    

    And following Java to get strings programmatically:

    res.getString(R.string.placeholder_string, mailCount)
    res.getQuantityString(R.plurals.plural_string, mailCount, mailCount)
    

    I am looking for the solution corresponding to Swift (iOS)