iOS: plurals and custom locale
Asked Answered
L

2

6

I'm developing app that supports "en" and "ru" languages, users can select language inside app.

If default phone's locale set to "en", but inside app selected "ru" language, then when trying to localize plural sentence ignored 'many'/'few' form. So it's localized by the English plural rules.

Definition:

<key>%d files</key>
    <dict>
        <key>NSStringLocalizedFormatKey</key>
        <string>%#@files@</string>
        <key>files</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>d</string>
            <key>one</key>
            <string>один файл</string>
            <key>many</key>
            <string>%d файлов</string>
            <key>other</key>
            <string>%d файла</string>
        </dict>
    </dict>

Code to localize (manually create 'ru' locale):

let locale = NSLocale(localeIdentifier: "ru_RU")
String(format: NSLocalizedString("%d files", comment: ""),
                    locale: locale,
                    count)

As output i got:
for count = 1: "один файл" - and it's right
for count = 2: "2 файла" - it's also right (from category 'other')
for count = 6: "6 файла" - wrong, also from category 'other', but should be taken from 'many'

If i switch phone's language to Russian, then all being localized correctly.

Lackadaisical answered 15/1, 2015 at 20:39 Comment(0)
F
1

You should use keys:

one for 1 = один файл

few for 2-4 = 2 файла

other for all other cases

Ferruginous answered 4/9, 2015 at 12:8 Comment(1)
I know how it should be filled :) And it works properly in default circumstances, but it has issues when used custom locale that doesn't match system language (e.g. if system language = 'en', but i use locale 'ru', which has different rules, then i will get wrong result)Lackadaisical
D
1

It is quite old question, but I've faced the same problem and this is how I fixed this:

let path = Bundle.main.path(forResource: "ru", ofType: "lproj")!
let bundle = Bundle(path: path)!
let localizedString = String(format: NSLocalizedString("%d files", bundle: bundle, comment: ""),
                                     locale: NSLocale(localeIdentifier: "ru_RU"),
                                     count)

The main idea is to make NSLocalizedString to search in language-specific bundle.

Donte answered 25/11, 2020 at 8:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.