Использование локализаций и кодов локали в iOS SDK
Почему это важно
Коды локали используются, когда Adapty выбирает локализацию для флоу или онбординга, а также когда вы читаете Remote Config для кастомного пейвола.
Коды локали могут различаться в зависимости от платформы, поэтому Adapty использует единый внутренний стандарт для всех поддерживаемых платформ. Понимание этого стандарта помогает предсказать, какую локализацию получит пользователь.
Стандарт кодов языков в Adapty
Для кодов языков Adapty использует слегка модифицированный стандарт BCP 47: каждый код состоит из подтегов в нижнем регистре, разделённых дефисами. Примеры: en (английский), pt-br (португальский (Бразилия)), zh (упрощённый китайский), zh-hant (традиционный китайский).
Соответствие кодов локалей
В SDK v4 флоу и онбординги используют разные подходы к сопоставлению кодов локалей: флоу локализуются SDK на устройстве, онбординги — сервером Adapty.
Флоу и пейволы, созданные в Paywall Builder
Пейвол, созданный в Paywall Builder, в SDK v4 доставляется как флоу, поэтому правило ниже распространяется на оба случая.
Совпадение точное. SDK сравнивает переданный вами код с кодами локализации флоу посимвольно: регистр не меняется, символы подчёркивания (_) не заменяются дефисами (-), и откат к языковому субтегу не выполняется. Для флоу с локализацией pt-br подходит только pt-br: варианты pt-BR, pt_BR и pt-PT не совпадут.
Если код не совпадает ни с одной локализацией, флоу молча отображается в локализации по умолчанию — SDK не возвращает ошибку и не выводит предупреждение.
Если код совпадает, Adapty объединяет найденную локализацию с локализацией по умолчанию: строки и ресурсы, которые не определены в найденной локализации, берутся из локализации по умолчанию.
Пропуск кода локали — это не то же самое, что запрос локализации флоу по умолчанию: SDK подставляет фиксированный en. Флоу, у которого локаль по умолчанию — de, всё равно отображается на en, если у него есть локализация en, и переключается на de только в том случае, если её нет.
Передавайте код локали точно так, как он настроен в дашборде — строчные буквы, подтеги разделены дефисами. Не передавайте системный идентификатор локали как есть: Locale.current.identifier возвращает pt_BR, а Locale.current.identifier(.bcp47) возвращает pt-BR, и оба значения откатываются к локализации по умолчанию. Преобразуйте значение в приложении перед передачей.
Онбординги
Онбординги локализуются на сервере, и серверные правила допускают другие форматы. Когда вы передаёте locale в getOnboarding:
- Строка локали приводится к нижнему регистру, а все символы подчёркивания (
_) заменяются дефисами (-) - Adapty ищет локализацию с полным совпадением кода локали
- Если совпадение не найдено, Adapty берёт подстроку до первого дефиса (
ptдляpt-br) и ищет соответствующую локализацию - Если совпадение снова не найдено, 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 в формате, описанном в разделе Стандарт кодов локалей в Adapty. SDK не сопоставляет Remote Config с локалью автоматически — выбор нужной записи остаётся за вашим приложением.
Почему это важно
Есть несколько сценариев, в которых коды локалей играют роль — например, когда нужно получить правильный пейвол для текущей локализации вашего приложения.
Поскольку коды локалей устроены непросто и могут отличаться от платформы к платформе, мы используем внутренний стандарт для всех поддерживаемых платформ. Именно из-за этой сложности важно понимать, что именно вы отправляете на наш сервер для получения нужной локализации и что происходит дальше — чтобы всегда получать именно то, что ожидаете.
Стандарт кодов локалей в Adapty
Для кодов локалей Adapty использует слегка модифицированный стандарт BCP 47: каждый код состоит из строчных подтегов, разделённых дефисами. Примеры: en (английский), pt-br (португальский (Бразилия)), zh (упрощённый китайский), zh-hant (традиционный китайский).
Сопоставление кода локали
Когда Adapty получает вызов от SDK с кодом локали и начинает искать соответствующую локализацию пейвола, происходит следующее:
- Входящая строка локали приводится к нижнему регистру, а все символы подчёркивания (
_) заменяются дефисами (-) - Затем мы ищем локализацию с полностью совпадающим кодом локали
- Если совпадение не найдено, берётся подстрока до первого дефиса (
ptдляpt-br) и выполняется поиск соответствующей локализации - Если совпадение снова не найдено, возвращается контент для локали пейвола по умолчанию
Таким образом устройство 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Мы не рекомендуем этот подход по ряду причин:
- На iOS предпочитаемые языки и текущая локаль — не одно и то же. Чтобы локализация выбиралась корректно, придётся либо полагаться на логику Apple (которая работает автоматически при использовании рекомендованного подхода с файлами локализованных строк), либо воссоздавать её самостоятельно.
- Сложно предсказать, что именно получит сервер Adapty. Например, на iOS устройство может вернуть локаль вида
ar_OM@numbers='latn', и в ответ вы получите не локализациюar-om, которую ожидали, аar— что, скорее всего, окажется неожиданным.
Если вы всё же решите использовать этот подход — убедитесь, что охватили все актуальные сценарии использования.