Kotlin Multiplatform SDK'da yerelleştirmeleri ve yerel ayar kodlarını kullanın

Bu neden önemlidir

Locale kodları, Adapty’nin bir flow veya onboarding için yerelleştirme seçerken ve özel paywall’lar için remote config okurken devreye girer.

Locale kodları karmaşık bir yapıya sahiptir ve platformdan platforma farklılık gösterebilir; bu nedenle Adapty, desteklediği her platformda tek bir dahili standarda dayanır. Bu standardı anlamak, kullanıcının hangi yerelleştirmeyi alacağını öngörmenize yardımcı olur.

Adapty’de yerel ayar kodu standardı

Adapty, yerel ayar kodları için hafif değiştirilmiş bir BCP 47 standardı kullanır: her kod, tire ile ayrılmış küçük harf alt etiketlerden oluşur. Bazı örnekler: en (İngilizce), pt-br (Portekizce (Brezilya)), zh (Basitleştirilmiş Çince), zh-hant (Geleneksel Çince).

Yerel ayar kodu eşleştirme

SDK v4’te flow’lar ve onboarding’ler yerel ayar kodlarını farklı şekillerde eşleştirir: flow’lar cihazda SDK tarafından, onboarding’ler ise Adapty sunucusu tarafından yerelleştirilir.

Flow’lar ve Paywall Builder Paywallları

Paywall Builder’da oluşturulmuş bir paywall, SDK v4’te flow olarak sunulur; dolayısıyla aşağıdaki kural her ikisi için de geçerlidir.

Eşleşme tam olarak yapılır. SDK, ilettiğiniz kodu flow’un yerelleştirme kodlarıyla karakter karakter karşılaştırır: büyük/küçük harf dönüşümü yapmaz, alt çizgi (_) ile kısa çizgiyi (-) birbirinin yerine kullanmaz ve dil alt etiketine geri dönmez. pt-br yerelleştirmesine sahip bir flow için yalnızca pt-br eşleşir: pt-BR, pt_BR ve pt-PT hiçbiri eşleşmez.

Kod hiçbir yerelleştirmeyle eşleşmediğinde, flow sessizce varsayılan yerel ayarında render edilir — SDK hata döndürmez ve uyarı kaydetmez.

Kod eşleştiğinde, Adapty eşleşen yerelleştirmeyi varsayılan olanla birleştirir: eşleşen yerelleştirmenin tanımlamadığı string’ler ve asset’ler varsayılan yerelleştirmeden alınır.

Yerel ayar kodunu atlamak, flow’un varsayılan yerelleştirmesini istemekle aynı şey değildir: SDK sabit olarak en kullanır. Varsayılan yerel ayarı de olan ve en yerelleştirmesi bulunan bir flow, en yerelleştirmesi varken en ile görüntülenir; yalnızca en yerelleştirmesi yoksa de’ye geri döner.

Locale kodunu tam olarak kontrol panelinde yapılandırıldığı şekilde iletin — küçük harfli alt etiketler kısa çizgiyle ayrılmış olmalıdır. Platform locale tanımlayıcısını olduğu gibi geçirmeyin: Android’de Locale.getDefault().toLanguageTag() pt-BR döndürür; iOS’ta NSLocale.currentLocale.localeIdentifier pt_BR döndürür. Her ikisi de varsayılan yerelleştirmeye geri düşer. Değeri uygulamanızda iletmeden önce dönüştürün.

Onboardings

Onboarding’ler sunucuda yerelleştirilir ve sunucu kuralları diğer biçimlere de tolerans gösterir. getOnboarding fonksiyonuna bir locale değeri ilettiğinizde:

  1. Locale dizesi küçük harfe dönüştürülür ve tüm alt çizgiler (_) kısa çizgi (-) ile değiştirilir
  2. Adapty, tam olarak eşleşen locale koduyla yerelleştirmeyi arar
  3. Eşleşme bulunamazsa, Adapty ilk kısa çizgiden önceki alt dizeyi alır (pt-br için pt) ve eşleşen yerelleştirmeyi arar
  4. Yine eşleşme bulunamazsa, Adapty onboarding’in varsayılan locale’ine ait içeriği döndürür

Bu sayede pt_BR, pt-BR ve pt-br hepsi aynı onboarding yerelleştirmesine çözümlenir.

Yerelleştirmeleri Uygulamak

SDK v4’te flow çekerken bir yerel ayar kodu göndermenize gerek yok — getFlow, flow’u tüm yerelleştirmeleriyle birlikte döndürür ve Adapty, flow görünümü oluşturulurken uygun olanı uygular.

  • Builder’da oluşturulan flow’lar: SDK, cihaz yerel ayarını okumaz; bu nedenle uygulamanızda çözümleyip createFlowView fonksiyonunun locale parametresi olarak geçin. Bu parametre isteğe bağlıdır — belirtmezseniz flow en dilinde görüntülenir ya da flow’un en yerelleştirmesi yoksa varsayılan yerel ayarında görüntülenir.

    import com.adapty.kmp.AdaptyUI
    
    AdaptyUI.createFlowView(flow = flow, locale = "es")
        .onSuccess { view ->
            view.present()
        }
        .onError { error ->
            // handle the error
        }

createNativeFlowView ve AdaptyUIFlowPlatformView composable’ı aynı isteğe bağlı locale parametresini alır. view.locale, view’ın hangi yerelleştirmeyle oluşturulduğunu bildirir. Hem locale parametresi hem de view.locale, Kotlin Multiplatform SDK 4.0.1-beta.1 veya daha yenisini gerektirir.

  • Özel (remote config) paywaller: getFlow, yapılandırılmış tüm yerelleştirmeleri flow.remoteConfigs içinde döndürür. Her giriş, bir locale kodu ve bir dataMap içeren AdaptyRemoteConfig nesnesidir. Kullanıcıyla eşleşen girişi kendi yedek mantığınızla seçin:

Adapty.getFlow("YOUR_PLACEMENT_ID")
    .onSuccess { flow ->
        val config = flow.remoteConfigs.firstOrNull { it.locale == "en" }
            ?: flow.remoteConfigs.firstOrNull()
        // read your values from config?.dataMap
    }
    .onError { error ->
        // handle the error
    }

Adapty, bu locale kodlarını Adapty’de Locale kodu standardı bölümünde açıklanan formatta saklar. SDK, remote config’leri bir locale ile eşleştirmez; dolayısıyla hangi girişin uygulanacağına uygulamanız karar verir.

Bu neden önemli

Yerel ayar kodlarının devreye girdiği birkaç senaryo vardır — örneğin, uygulamanızın mevcut yerelleştirmesi için doğru paywall’ı almaya çalışırken.

Yerel ayar kodları karmaşık olduğundan ve platformdan platforma farklılık gösterebildiğinden, desteklediğimiz tüm platformlar için dahili bir standarda dayanıyoruz. Ancak bu kodlar karmaşık olduğu için, doğru yerelleştirmeyi almak üzere sunucumuza tam olarak ne gönderdiğinizi ve ardından ne olduğunu anlamanız son derece önemlidir; böylece her zaman beklediğinizi alırsınız.

Adapty’de locale kodu standardı

Adapty, locale kodları için hafifçe değiştirilmiş bir BCP 47 standardı kullanır: her kod, kısa çizgilerle ayrılmış küçük harfli alt etiketlerden oluşur. Birkaç örnek: en (İngilizce), pt-br (Portekizce (Brezilya)), zh (Basitleştirilmiş Çince), zh-hant (Geleneksel Çince).

Yerel ayar kodu eşleştirme

Adapty, istemci tarafı SDK’dan yerel ayar koduyla bir çağrı alıp paywall’ın ilgili yerelleştirmesini aramaya başladığında şu adımlar gerçekleşir:

  1. Gelen yerel ayar dizesi küçük harfe dönüştürülür ve tüm alt çizgiler (_) kısa çizgiyle (-) değiştirilir
  2. Ardından tam olarak eşleşen yerel ayar koduna sahip yerelleştirme aranır
  3. Eşleşme bulunamazsa, ilk kısa çizgiden önceki alt dize alınır (pt-br için pt) ve eşleşen yerelleştirme aranır
  4. Yine eşleşme bulunamazsa, paywall’ın varsayılan yerel ayarına ait içerik döndürülür

Bu sayede 'pt_BR' gönderen bir iOS cihazı, pt-BR gönderen bir Android cihazı ve pt-br gönderen başka bir cihaz aynı sonucu alacaktır.

Lokalizasyonlarla ilgileniyorsanız, büyük ihtimalle projenizdeki lokalize edilmiş string kaynaklarıyla zaten çalışıyorsunuzdur. Eğer öyleyse, her kaynak dosyanıza ilgili lokalizasyon için Adapty locale kodu içeren bir anahtar-değer çifti eklemenizi öneririz. Ardından SDK’mızı çağırırken bu anahtarın değerini şu şekilde çekebilirsiniz:

// 1. Adapty yerel ayar kodunu Compose Multiplatform kaynaklarınıza ekleyin

/*
composeResources/values/strings.xml (varsayılan — İngilizce)
*/
<string name="adapty_paywalls_locale">en</string>

/*
composeResources/values-es/strings.xml (İspanyolca)
*/
<string name="adapty_paywalls_locale">es</string>

/*
composeResources/values-pt-rBR/strings.xml (Portekizce — Brezilya)
*/
<string name="adapty_paywalls_locale">pt-br</string>

// 2. Yerel ayar kodunu çıkarın ve kullanın

suspend fun fetchPaywall() {
    val locale = getString(Res.string.adapty_paywalls_locale)
    Adapty.getPaywall(
        placementId = "YOUR_PLACEMENT_ID",
        locale = locale
    ).onSuccess { paywall ->
        // istenen paywall
    }.onError { error ->
        // hatayı işle
    }
}

Bu sayede uygulamanızın her kullanıcısı için hangi yerelleştirmenin alınacağı üzerinde tam kontrol sahibi olursunuz.

Compose Multiplatform kaynakları kullanmıyorsanız, aynı fikir kullandığınız herhangi bir yerelleştirme kütüphanesi için de geçerlidir (örneğin, moko-resources) — Adapty yerel ayar kodunu her yerel ayarın kaynak paketinde bir dize olarak saklayın ve SDK’yı çağırmadan önce okuyun.

Yerelleştirmeleri uygulama: alternatif yol

Her yerelleştirme için açıkça dil kodu tanımlamadan da benzer (ancak aynı değil) sonuçlar elde edebilirsiniz. Bu yaklaşım, dil kodunu doğrudan cihazdan çıkarmak anlamına gelir; ancak commonMain içinde ortak bir dil kodu API’si olmadığından expect/actual bildirimleri gereklidir:

// 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 ->
        // istenen paywall
    }.onError { error ->
        // hatayı işle
    }
}

Birkaç nedenden dolayı bu yaklaşımı önermiyoruz:

  1. iOS’ta kullanıcının tercih ettiği dil ile cihazın bölgesel yerel ayarı aynı değildir. NSLocale.currentLocale.localeIdentifier, kullanıcının uygulamanızı gerçekte hangi dilde okuduğuyla örtüşmeyebilecek bölgesel yerel ayarı döndürür. Yerelleştirilmiş string dosyaları kullanan iOS uygulamaları, her ikisini birleştirmek için Apple’ın çözümleme mantığına dayanır; bu da yukarıdaki önerilen yaklaşımla doğrudan çalışır.
  2. Cihazın tam olarak ne döndüreceğini ve bunun Adapty’deki bir yerelleştirmeyle eşleşip eşleşmeyeceğini tahmin etmek güçtür. Cihaz yerel ayarı, Adapty’de yapılandırmadığınız uzantılar veya bölge kodları içerebilir; bu durumda SDK, ilk alt etikete göre eşleşmeye ya da nihayetinde en diline geri döner. Bu yaklaşımı kullanmaya karar verirseniz, ilgili tüm kullanım senaryolarını kapsadığınızdan emin olun.