0Pricing
Swift Academy · Урок

Множественное число и Stringsdict

Обрабатывайте правила образования множественного числа в разных языках.

«Множественное число и Stringsdict» — бесплатный урок Swift Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.

Проблема форм множественного числа

В английском языке две формы — 1 item и 2 items, поэтому разработчики часто пишут "\(n) item" + (n == 1 ? "" : "s"). Такой подход плохо работает: в арабском языке шесть категорий множественного числа, в русском три, а в японском одна. Жёстко заданная логика выбора формы — это ошибка локализации, которая только и ждёт своего часа.

// FRAGILE — only works for English
let n = 5
let bad = "\(n) item" + (n == 1 ? "" : "s")
print(bad)

Категории множественного числа

Unicode определяет категории множественного числа: ноль, один, два, несколько, много, другое. Каждый язык использует их подмножество. Система выбирает правильную категорию для числа на основе правил локали — Вам не нужно писать эти правила самостоятельно.

// English uses: one, other
// Russian uses: one, few, many, other
// Japanese uses: other (only)
// You provide a variant string per category needed.

Варианты множественного числа в каталоге строк

В каталоге строк можно отметить строку как имеющую варианты для разных форм множественного числа. После этого Xcode позволяет указать текст для каждой категории. Во время выполнения нужный вариант автоматически выбирается на основе интерполированного количества и локали пользователя.

// Catalog entry, key "message_count":
//   one:   "You have %lld message"
//   other: "You have %lld messages"
let count = 1
let text = String(localized: "You have \(count) messages")
print(text)

Устаревший файл .stringsdict

До появления каталогов строк формы множественного числа хранились в файле .stringsdict — списке свойств, сопоставляющем ключ с форматной строкой и вариантами для каждой категории. Такие файлы всё ещё встречаются в старых проектах и полностью поддерживаются.

// Localizable.stringsdict (plist) structure:
// key: "items_count"
//   NSStringLocalizedFormatKey: "%#@items@"
//   items: NSStringPluralRuleType
//     one:   "%lld item"
//     other: "%lld items"

Структура записи stringsdict

Каждая запись содержит ключ формата, ссылающийся на одну или несколько именованных переменных, заключённых в %#@name@. Каждая переменная объявляет тип правила (NSStringPluralRuleType), спецификатор типа значения (%lld) и строку для каждой категории множественного числа.

// The %#@items@ token expands to the chosen
// plural variant. %lld is the integer placeholder
// substituted inside each variant string.
let n = 3
print(String(localized: "\(n) items selected"))

Получение строки с учётом числа

Вызов из кода выглядит так же, как для любой локализованной строки: нужно лишь интерполировать количество. Выбор формы числа выполняется внутри фреймворка, поэтому одна и та же строка Swift работает на любом языке.

func messagesLabel(_ count: Int) -> String {
    return String(localized: "You have \(count) messages")
}
print(messagesLabel(0))
print(messagesLabel(1))
print(messagesLabel(7))

Почему «один» — это не просто 1

Распространённая ошибка — считать, что категория один означает ровно число 1. В некоторых языках она охватывает любое число, оканчивающееся на 1 (например, 21 или 31), а категория ноль может быть отдельной или отсутствовать. Всегда предоставляйте текст для каждой категории, а выбор оставляйте правилам языка.

// Russian: 1, 21, 31 -> 'one'
//          2, 3, 4    -> 'few'
//          5..20, 0   -> 'many'
// Never assume one == 1.

Сочетание форм числа с другими значениями

Формат может содержать несколько переменных — например, количество и имя. Для каждой из них форма числа может определяться независимо. В каталоге строк укажите, какая интерполяция изменяется, а остальные части останутся постоянными во всех вариантах.

let files = 2
let folder = "Photos"
let text = String(
    localized: "\(files) files in \(folder)")
// 'files' drives the plural; 'folder' is substituted as-is
print(text)

Варианты ширины и устройств

Тот же механизм каталога поддерживает варианты устройства и ширины: на часах можно показать короткую подпись, а на iPad — более длинную, либо использовать сокращение, когда места мало. Эти варианты работают вместе с вариантами форм числа.

// Catalog can vary by:
//   plural: one / other
//   device: iPhone / iPad / watch
//   width:  short / medium / long
let label = String(localized: "Notifications")
print(label)

Проверка форм числа

Чтобы проверить варианты, запустите приложение для каждого целевого языка, используя переопределение локализации схемы в Xcode, либо примените псевдоязык и предпросмотры для отдельных локалей. Проверьте пограничные значения: 0, 1, 2, 5, 11, 21, 100.

let samples = [0, 1, 2, 5, 11, 21, 100]
for n in samples {
    print(String(localized: "\(n) items"))
}

Рекомендации

Чтобы формы числа были корректными:

  • Никогда не добавляйте окончания s конкатенацией или вручную.
  • Предоставляйте все категории, необходимые целевым языкам.
  • Определяйте форму числа по интерполированному целому числу, а не по заранее сформированной строке.
  • Для нового кода отдавайте предпочтение каталогам строк; используйте .stringsdict только для устаревших целевых платформ.
func cartSummary(_ items: Int) -> String {
    String(localized: "Your cart has \(items) items",
           comment: "Cart count; pluralized")
}
print(cartSummary(1))

Быстрая проверка

Вспомните, как должен выполняться выбор формы числа.

Итоги

Вы научились выбирать формы числа с учётом локали:

  • Категории числа Unicode — ноль, один, два, несколько, много, другое; каждый язык использует их подмножество.
  • Каталоги строк позволяют добавлять варианты форм числа для каждого ключа; устаревший формат .stringsdict делает то же самое с помощью plist.
  • Места вызова остаются простыми: интерполируйте количество, а фреймворк выберет вариант.
  • Никогда не задавайте логику форм числа вручную: категория один означает не только число 1.

Часто задаваемые вопросы

Урок «Множественное число и Stringsdict» бесплатный?

Да — полный текст урока «Множественное число и Stringsdict» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.

Чему я научусь в уроке «Множественное число и Stringsdict»?

Обрабатывайте правила образования множественного числа в разных языках. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Swift Academy?

Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Множественное число и Stringsdict»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Swift Academy?

Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Каталоги строк и локализованные строки
  2. Множественное число и Stringsdict
  3. Форматирование с учётом локали
  4. Справа налево и направление компоновки
← Назад к Swift Academy