Usar localizaciones y códigos de idioma en el SDK de Unity

Por qué esto es importante

Los códigos de idioma entran en juego cuando Adapty selecciona la localización para un flow o un onboarding, y cuando lees un Remote Config para un paywall personalizado.

Los códigos de idioma son complejos y pueden variar de una plataforma a otra, por lo que Adapty utiliza un estándar interno único en todas las plataformas que admite. Entender ese estándar te ayuda a predecir qué localización recibirá cada usuario.

Estándar de códigos de idioma en Adapty

Para los códigos de idioma, Adapty utiliza una versión ligeramente modificada del estándar BCP 47: cada código se compone de subetiquetas en minúsculas separadas por guiones. Algunos ejemplos: en (inglés), pt-br (portugués (Brasil)), zh (chino simplificado), zh-hant (chino tradicional).

Coincidencia de códigos de idioma

En SDK v4, los flows y los onboardings coinciden con los códigos de idioma de forma diferente: los flows se localizan mediante el SDK en el dispositivo, los onboardings mediante el servidor de Adapty.

Flows y paywalls del Paywall Builder

Un paywall construido en el Paywall Builder se entrega como un flow en el SDK v4, por lo que la regla siguiente aplica a ambos.

La coincidencia es exacta. El SDK compara el código que proporcionas con los códigos de localización del flow carácter a carácter: no cambia las mayúsculas, no reemplaza los guiones bajos (_) por guiones (-) ni recurre a la subtag de idioma. Para un flow con la localización pt-br, solo pt-br coincide: pt-BR, pt_BR y pt-PT no lo hacen.

Cuando el código no coincide con ninguna localización, el flow se renderiza silenciosamente en su localización predeterminada — el SDK no devuelve un error ni registra ninguna advertencia.

Cuando el código coincide, Adapty combina la localización con la predeterminada: las cadenas y recursos que la localización coincidente no define se obtienen de la localización predeterminada.

Omitir el código de idioma no es lo mismo que solicitar la localización predeterminada del flow: el SDK sustituye un en fijo. Un flow cuyo idioma predeterminado es de se renderiza en en si tiene una localización para en, y solo vuelve a de cuando no la tiene.

Pasa el código de idioma exactamente como está configurado en el dashboard: subtags en minúsculas separadas por guiones. No pases un identificador de locale del sistema tal cual: CultureInfo.CurrentCulture.Name devuelve pt-BR, y vuelve a la localización predeterminada. Convierte el valor en tu app antes de pasarlo.

Onboardings

Los onboardings se localizan en el servidor, y las reglas del servidor toleran otros formatos. Cuando pasas un Locale a GetOnboarding:

  1. La cadena de configuración regional se convierte a minúsculas y todos los guiones bajos (_) se reemplazan por guiones (-)
  2. Adapty busca la localización con el código de configuración regional que coincida exactamente
  3. Si no se encuentra ninguna coincidencia, Adapty toma la subcadena anterior al primer guión (pt para pt-br) y busca la localización correspondiente
  4. Si tampoco se encuentra ninguna coincidencia, Adapty devuelve el contenido para la configuración regional predeterminada del onboarding

Esta forma, pt_BR, pt-BR y pt-br resuelven a la misma localización de onboarding.

Implementación de localizaciones

En SDK v4, no se pasa un código de idioma al obtener un flow; el flow se localiza cuando se crea su vista.

  • Paywalls de Flow Builder y Paywall Builder: el SDK no lee el idioma del dispositivo, así que resuélvelo en tu app y pásalo al crear la vista. El código de idioma es opcional: omítelo y el flow se renderizará en en, o en su idioma predeterminado si el flow no tiene localización en.
  • Paywalls personalizados (Remote Config): GetFlow devuelve todas las localizaciones configuradas en flow.RemoteConfigs. Cada entrada es un AdaptyRemoteConfig con un código Locale y un Dictionary de valores. Selecciona la entrada que corresponda al usuario, con tu propia lógica de respaldo:
using System.Linq;
using AdaptySDK;

Adapty.GetFlow("YOUR_PLACEMENT_ID", (flow, error) => {
    if (error != null) {
        // handle the error
        return;
    }

    var config = flow.RemoteConfigs.FirstOrDefault(c => c.Locale == "en")
        ?? flow.RemoteConfigs.FirstOrDefault();
    // read your values from config?.Dictionary
});

Adapty almacena los códigos Locale en el formato descrito en Estándar de código de idioma en Adapty. El SDK no compara los Remote Configs con un idioma automáticamente, así que es tu app quien decide qué entrada aplicar.

Elige la localización de un flow

Para renderizar un flow o paywall con una localización específica, pasa el código de idioma a SetLocale al crear la vista:

var parameters = new AdaptyUICreateFlowViewParameters()
    .SetLocale("pt-br");

AdaptyUI.CreateFlowView(flow, parameters, (view, error) => {
    if (error != null) {
        // handle the error
        return;
    }

    // view.Locale — the localization the view was built with
});

La vista informa de la localización con la que se ha construido en view.Locale: la que solicitaste si esa localización existe, o la localización predeterminada del flow en caso contrario.

Por qué esto es importante

Hay algunos escenarios en los que los códigos de idioma entran en juego — por ejemplo, cuando intentas obtener el paywall correcto para la localización actual de tu app.

Como los códigos de idioma son complejos y pueden variar de una plataforma a otra, nos basamos en un estándar interno para todas las plataformas que soportamos. Sin embargo, precisamente porque estos códigos son complejos, es muy importante que entiendas exactamente qué estás enviando a nuestro servidor para obtener la localización correcta y qué ocurre a continuación — así siempre recibirás lo que esperas.

Estándar de códigos de idioma en Adapty

Para los códigos de idioma, Adapty utiliza una versión ligeramente modificada del estándar BCP 47: cada código se compone de subetiquetas en minúsculas separadas por guiones. Algunos ejemplos: en (inglés), pt-br (portugués de Brasil), zh (chino simplificado), zh-hant (chino tradicional).

Coincidencia de código de idioma

Cuando Adapty recibe una llamada del SDK con el código de idioma y comienza a buscar la localización correspondiente de un paywall, ocurre lo siguiente:

  1. La cadena de idioma recibida se convierte a minúsculas y todos los guiones bajos (_) se reemplazan por guiones (-)
  2. A continuación, se busca la localización con el código de idioma que coincida exactamente
  3. Si no se encuentra ninguna coincidencia, se toma la subcadena anterior al primer guión (pt para pt-br) y se busca la localización correspondiente
  4. Si tampoco se encuentra ninguna coincidencia, se devuelve el contenido para el idioma predeterminado del paywall

De este modo, un dispositivo iOS que envió 'pt_BR', un dispositivo Android que envió pt-BR y otro dispositivo que envió pt-br obtendrán el mismo resultado.

Si te estás preguntando cómo gestionar las localizaciones, probablemente ya estés trabajando con archivos de cadenas localizadas en tu proyecto. En ese caso, te recomendamos añadir un par clave-valor con el código de idioma de Adapty correspondiente en cada uno de esos archivos. Luego, extrae el valor de esa clave al llamar a nuestro SDK, así:

// 1. Modify your localization files (e.g., using Unity's Localization package)

/*
en.json
*/
{
  "adapty_paywalls_locale": "en"
}

/*
es.json
*/
{
  "adapty_paywalls_locale": "es"
}

/*
pt-BR.json
*/
{
  "adapty_paywalls_locale": "pt-br"
}

// 2. Extract and use the locale code
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using AdaptySDK;

public class PaywallManager : MonoBehaviour
{
    public async void FetchPaywall()
    {
        // Get the current locale from Unity's Localization system
        var locale = LocalizationSettings.SelectedLocale;
        var localeCode = GetAdaptyLocaleCode(locale);
        
        // Pass locale code to Adapty.GetPaywall or Adapty.GetPaywallForDefaultAudience method
        Adapty.GetPaywall("placement_id", localeCode, (paywall, error) => {
            if (error != null) {
                // handle the error
                return;
            }
            // Use the paywall
        });
    }
    
    private string GetAdaptyLocaleCode(Locale locale)
    {
        // Convert Unity locale to Adapty format
        var localeIdentifier = locale.Identifier.Code;
        return localeIdentifier.ToLower().Replace('_', '-');
    }
}

Así te aseguras de tener control total sobre qué localización se recuperará para cada usuario de tu app.

Implementar localizaciones: otra forma

Puedes obtener resultados similares (aunque no idénticos) sin definir explícitamente códigos de idioma para cada localización. Esto implicaría extraer un código de idioma de otros objetos que proporciona tu plataforma, así:

using UnityEngine;
using System.Globalization;
using AdaptySDK;

public class PaywallManager : MonoBehaviour
{
    public void FetchPaywall()
    {
        var localeCode = GetSystemLocaleCode();
        
        // Pass locale code to Adapty.GetPaywall or Adapty.GetPaywallForDefaultAudience method
        Adapty.GetPaywall("placement_id", localeCode, (paywall, error) => {
            if (error != null) {
                // handle the error
                return;
            }
            // Use the paywall
        });
    }
    
    private string GetSystemLocaleCode()
    {
        // Get the system's current culture
        var culture = CultureInfo.CurrentCulture;
        var languageCode = culture.TwoLetterISOLanguageName;
        var regionCode = culture.Name.Contains('-') ? culture.Name.Split('-')[1] : null;
        
        if (!string.IsNullOrEmpty(regionCode))
        {
            return $"{languageCode}-{regionCode.ToLower()}";
        }
        
        return languageCode;
    }
}

Ten en cuenta que no recomendamos este enfoque por varias razones:

  1. En iOS, los idiomas preferidos y la configuración regional actual no son idénticos. Si quieres que la localización se seleccione correctamente, tendrás que apoyarte en la lógica de Apple, que funciona de forma nativa si usas el enfoque recomendado con archivos de cadenas localizadas, o recrearla manualmente.
  2. Es difícil predecir exactamente qué recibirá el servidor de Adapty. Por ejemplo, en iOS es posible obtener una configuración regional como ar_OM@numbers='latn' en un dispositivo y enviarla a nuestro servidor. En ese caso, en lugar de la localización ar-om que buscabas, recibirás ar, lo cual probablemente no es lo esperado. Should you decide to use this approach anyway — make sure you’ve covered all the relevant use cases.