Использование локализаций и кодов локали в iOS SDK

Почему это важно

Коды локалей используются, когда Adapty выбирает локализацию для флоу и когда вы читаете Remote Config для кастомного пейвола.

Коды локалей устроены непросто и могут различаться в зависимости от платформы, поэтому Adapty придерживается единого внутреннего стандарта для всех поддерживаемых платформ. Понимание этого стандарта поможет вам предсказать, какую локализацию получит пользователь.

Стандарт кодов языков в Adapty

Для кодов языков Adapty использует слегка модифицированный стандарт BCP 47: каждый код состоит из подтегов в нижнем регистре, разделённых дефисами. Примеры: en (английский), pt-br (португальский (Бразилия)), zh (упрощённый китайский), zh-hant (традиционный китайский).

Сопоставление кода локали

Когда Adapty ищет локализацию, соответствующую локали пользователя, происходит следующее:

  1. Строка локали приводится к нижнему регистру, а все символы подчёркивания (_) заменяются дефисами (-)
  2. Adapty ищет локализацию с полностью совпадающим кодом локали
  3. Если совпадение не найдено, Adapty берёт подстроку до первого дефиса (pt для pt-br) и ищет соответствующую локализацию
  4. Если совпадение снова не найдено, Adapty возвращает контент для локали флоу по умолчанию

Таким образом, 'pt_BR', pt-BR и pt-br — все они указывают на одну и ту же локализацию.

Реализация локализаций

В SDK v4 при получении флоу вам не нужно передавать код локали — getFlow возвращает флоу со всеми его локализациями.

  • Флоу, созданные в билдере: SDK не считывает локаль устройства, поэтому определите её в своём приложении и передайте в AdaptyUI.getFlowConfiguration(forFlow:locale:). Параметр необязателен — если его не указать, флоу отобразится на en или в локали по умолчанию, если локализация en не настроена.
  • Пользовательские (Remote Config) пейволы: getFlow возвращает все настроенные локализации в flow.remoteConfigs. У каждой записи есть код locale и содержимое конфига (jsonString или разобранный dictionary). Выберите нужную запись для пользователя, реализовав собственный фолбэк:
do {
    let flow = try await Adapty.getFlow(placementId: "YOUR_PLACEMENT_ID")
    let config = flow.remoteConfigs.first(where: { $0.locale == "en" })
        ?? flow.remoteConfigs.first
    // read your values from config?.dictionary
} catch {
    // handle the error
}

Правила сопоставления кода локали, описанные выше, показывают, как Adapty нормализует коды locale, хранящиеся в каждом Remote Config.

Почему это важно

Есть несколько сценариев, в которых коды локалей играют роль — например, когда нужно получить правильный пейвол для текущей локализации вашего приложения.

Поскольку коды локалей устроены непросто и могут отличаться от платформы к платформе, мы используем внутренний стандарт для всех поддерживаемых платформ. Именно из-за этой сложности важно понимать, что именно вы отправляете на наш сервер для получения нужной локализации и что происходит дальше — чтобы всегда получать именно то, что ожидаете.

Стандарт кодов локалей в Adapty

Для кодов локалей Adapty использует слегка модифицированный стандарт BCP 47: каждый код состоит из строчных подтегов, разделённых дефисами. Примеры: en (английский), pt-br (португальский (Бразилия)), zh (упрощённый китайский), zh-hant (традиционный китайский).

Сопоставление кода локали

Когда Adapty получает вызов от SDK с кодом локали и начинает искать соответствующую локализацию пейвола, происходит следующее:

  1. Входящая строка локали приводится к нижнему регистру, а все символы подчёркивания (_) заменяются дефисами (-)
  2. Затем мы ищем локализацию с полностью совпадающим кодом локали
  3. Если совпадение не найдено, берётся подстрока до первого дефиса (pt для pt-br) и выполняется поиск соответствующей локализации
  4. Если совпадение снова не найдено, возвращается контент для локали пейвола по умолчанию

Таким образом устройство iOS, отправившее 'pt_BR', устройство Android, отправившее pt-BR, и другое устройство, отправившее pt-br, получат одинаковый результат.

Если вас интересуют локализации, скорее всего, вы уже работаете с файлами локализованных строк в своём проекте. В таком случае мы рекомендуем добавить пару ключ-значение с нужным кодом языка Adapty в каждый из ваших файлов для соответствующих локализаций, а затем извлекать значение по этому ключу при вызове нашего SDK:

// 1. Modify your Localizable.strings files

/*
Localizable.strings - Spanish
*/
adapty_paywalls_locale = "es";
/*
Localizable.strings - Portuguese (Brazil)
*/
adapty_paywalls_locale = "pt-br";
// 2. Extract and use the locale code
let locale = NSLocalizedString("adapty_paywalls_locale", comment: "")
// pass locale code to AdaptyUI.getViewConfiguration or Adapty.getPaywall method

Так вы полностью контролируете, какая локализация будет загружена для каждого пользователя вашего приложения.

Реализация локализаций: альтернативный способ

Похожего (но не идентичного) результата можно добиться, не задавая явно коды языков для каждой локализации. Для этого нужно извлекать код языка из других объектов, предоставляемых платформой:

let locale = Locale.current.identifier
// pass locale code to AdaptyUI.getViewConfiguration or Adapty.getPaywall method

Мы не рекомендуем этот подход по ряду причин:

  1. На iOS предпочитаемые языки и текущая локаль — не одно и то же. Чтобы локализация выбиралась корректно, придётся либо полагаться на логику Apple (которая работает автоматически при использовании рекомендованного подхода с файлами локализованных строк), либо воссоздавать её самостоятельно.
  2. Сложно предсказать, что именно получит сервер Adapty. Например, на iOS устройство может вернуть локаль вида ar_OM@numbers='latn', и в ответ вы получите не локализацию ar-om, которую ожидали, а ar — что, скорее всего, окажется неожиданным.

Если вы всё же решите использовать этот подход — убедитесь, что охватили все актуальные сценарии использования.