Использование локализаций и кодов локали в Kotlin Multiplatform SDK
Почему это важно
Есть несколько сценариев, где в игру вступают коды локалей — например, когда нужно получить правильный пейвол для текущей локализации приложения.
Поскольку коды локалей сложны и могут отличаться от платформы к платформе, мы опираемся на внутренний стандарт для всех поддерживаемых платформ. Но именно из-за этой сложности важно понимать, что именно вы отправляете на наш сервер для получения нужной локализации и что происходит дальше — чтобы всегда получать то, что ожидаете.
Стандарт кодов локалей в Adapty
Для кодов локалей Adapty использует немного модифицированный стандарт BCP 47: каждый код состоит из строчных подтегов, разделённых дефисами. Примеры: en (английский), pt-br (португальский (Бразилия)), zh (упрощённый китайский), zh-hant (традиционный китайский).
Сопоставление кодов локали
Когда Adapty получает вызов от клиентского SDK с кодом локали и начинает искать соответствующую локализацию пейвола, происходит следующее:
- Входящая строка локали приводится к нижнему регистру, а все символы подчёркивания (
_) заменяются дефисами (-) - Выполняется поиск локализации с точным совпадением кода локали
- Если совпадение не найдено, берётся подстрока до первого дефиса (
ptдляpt-br) и выполняется поиск по ней - Если совпадение снова не найдено, возвращается локализация по умолчанию —
enТаким образом, устройство iOS, отправившее'pt_BR', устройство Android, отправившееpt-BR, и другое устройство, отправившееpt-br, получат одинаковый результат.
Реализация локализаций: рекомендуемый способ
Если вы думаете о локализациях, скорее всего, вы уже работаете с локализованными строковыми ресурсами в своём проекте. В таком случае мы рекомендуем добавить пару ключ-значение с нужным кодом локали Adapty в каждый из ваших файлов ресурсов для соответствующих локализаций. А затем извлекать значение по этому ключу при вызове нашего SDK, например так:
// 1. Add the Adapty locale code to your Compose Multiplatform resources
/*
composeResources/values/strings.xml (default — English)
*/
<string name="adapty_paywalls_locale">en</string>
/*
composeResources/values-es/strings.xml (Spanish)
*/
<string name="adapty_paywalls_locale">es</string>
/*
composeResources/values-pt-rBR/strings.xml (Portuguese — Brazil)
*/
<string name="adapty_paywalls_locale">pt-br</string>
// 2. Extract and use the locale code
suspend fun fetchPaywall() {
val locale = getString(Res.string.adapty_paywalls_locale)
Adapty.getPaywall(
placementId = "YOUR_PLACEMENT_ID",
locale = locale
).onSuccess { paywall ->
// запрошенный пейвол
}.onError { error ->
// обработка ошибки
}
}
Таким образом вы полностью контролируете, какая локализация будет получена для каждого пользователя вашего приложения.
Если вы не используете ресурсы Compose Multiplatform, та же идея применима к любой другой библиотеке локализации (например, moko-resources) — сохраните код локали Adapty как строку в ресурсном бандле каждой локали и считайте его перед вызовом SDK.
Реализация локализаций: альтернативный подход
Можно получить похожий (но не идентичный) результат, не указывая явно коды локалей для каждой локализации. Для этого нужно извлекать код локали напрямую с устройства — но это потребует объявлений expect/actual, поскольку в commonMain нет общего API для работы с локалями:
// commonMain
expect fun currentLocaleTag(): String
// androidMain
actual fun currentLocaleTag(): String = Locale.getDefault().toLanguageTag()
// iosMain
actual fun currentLocaleTag(): String = NSLocale.currentLocale.localeIdentifier
// commonMain — pass the locale code to Adapty
suspend fun fetchPaywall() {
Adapty.getPaywall(
placementId = "YOUR_PLACEMENT_ID",
locale = currentLocaleTag()
).onSuccess { paywall ->
// the requested paywall
}.onError { error ->
// handle the error
}
}
Обратите внимание, что мы не рекомендуем этот подход по ряду причин:
- На iOS предпочитаемый язык пользователя и региональная локаль устройства — не одно и то же.
NSLocale.currentLocale.localeIdentifierвозвращает региональную локаль, которая может отличаться от языка, на котором пользователь читает ваше приложение. iOS-приложения, использующие локализованные строковые файлы, опираются на логику разрешения Apple, которая объединяет оба параметра — это работает автоматически при использовании рекомендованного подхода выше. - Сложно предсказать, что именно вернёт устройство и совпадёт ли это с локализацией в Adapty. Локаль устройства может содержать расширения или региональные коды, которые вы не настроили в Adapty — в этом случае SDK откатывается до совпадения по первому подтегу или, в крайнем случае, до
en. Should you decide to use this approach anyway — make sure you’ve covered all the relevant use cases.