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

Por qué esto es importante

Los códigos de idioma entran en juego cuando Adapty elige 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 recibe 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 consiste en subtags 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 hacen coincidir los códigos de idioma de forma diferente: los flows se localizan mediante el SDK en el dispositivo, y los onboardings, mediante el servidor de Adapty.

Flows y paywalls del Paywall Builder

Un paywall creado en el Paywall Builder se entrega como un flow en el SDK v4, por lo que la regla siguiente cubre ambos casos.

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

Cuando el código no coincide con ninguna localización, el flow se renderiza en su idioma predeterminado — el SDK no devuelve ningún error ni registra ningún aviso.

Cuando el código sí coincide, Adapty fusiona la localización con la predeterminada: las cadenas de texto y los 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 seguirá renderizándose en en si tiene una localización en en, y solo recurrirá al de cuando no la tenga.

Pasa el código de idioma exactamente como está configurado en el dashboard — subtags en minúsculas separados por guiones. No pases un identificador de configuración regional del sistema tal cual: Platform.localeName devuelve pt_BR y PlatformDispatcher.instance.locale.toLanguageTag() devuelve pt-BR, y ambos recurren a la localización predeterminada. Convierte el valor en tu aplicación antes de pasarlo.

Onboardings

Los onboardings se localizan en el servidor, y las reglas del servidor admiten otros formatos. Cuando pasas un locale a getOnboarding:

  1. La cadena de locale 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 locale que coincida exactamente
  3. Si no se encuentra ninguna coincidencia, Adapty toma la subcadena anterior al primer guion (pt para pt-br) y busca la localización que coincida
  4. Si tampoco se encuentra ninguna coincidencia, Adapty devuelve el contenido para el locale predeterminado del onboarding

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

Implementación de localizaciones

En el SDK v4, no es necesario pasar un código de idioma al obtener un flow: getFlow devuelve el flow con todas sus localizaciones, y Adapty aplica una cuando se construye la vista del flow. El argumento locale de getFlow y getFlowForDefaultAudience no tiene efecto en los flows; está obsoleto y registra una advertencia.

  • Flows creados en el builder: el SDK no lee el idioma del dispositivo, así que resuélvelo en tu app y pásalo como argumento locale de createFlowView o AdaptyUIFlowPlatformView. El argumento es opcional — si lo omites, el flow se renderiza en en, o en su idioma predeterminado cuando el flow no tiene localización en.

AdaptyUIFlowView.locale informa la localización con la que se construyó la vista. Requiere Flutter SDK 4.0.3 con las versiones nativas iOS 4.0.2 y Android 4.0.1, y es null con SDKs nativos más antiguos.

  • Paywalls personalizados (Remote Config): getFlow devuelve todas las localizaciones configuradas en flow.remoteConfigs. Cada entrada tiene un código locale y el contenido de la configuración (cadena data o el dictionary parseado). Selecciona la entrada que corresponda al usuario, con tu propio fallback:

final flow = await Adapty().getFlow(placementId: 'YOUR_PLACEMENT_ID');
final config = flow.remoteConfigs.firstWhereOrNull((c) => c.locale == 'en') ??
    flow.remoteConfig; // the first remote config, if present
// read your values from config?.dictionary

Adapty almacena esos códigos locale en el formato descrito en Estándar de código de locale en Adapty. El SDK no compara los Remote Configs con un locale, por lo que tu app es quien decide qué entrada aplicar.

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 complicados y pueden variar de una plataforma a otra, nos basamos en un estándar interno para todas las plataformas que soportamos. Sin embargo, precisamente por esa complejidad, 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 usa una versión ligeramente modificada del estándar BCP 47: cada código está formado por 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

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

  1. La cadena de idioma entrante se convierte a minúsculas y todos los guiones bajos (_) se reemplazan por guiones (-)
  2. A continuación, se busca la localización cuyo código de idioma coincida exactamente
  3. Si no se encuentra ninguna coincidencia, se toma la subcadena anterior al primer guión (pt en pt-br) y se busca la localización correspondiente
  4. Si tampoco se encuentra ninguna coincidencia, se devuelve el contenido del 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 estás pensando en las localizaciones, lo más probable es que ya trabajes 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 tus archivos para las localizaciones. Después, extrae el valor de esa clave al llamar a nuestro SDK, así:

// 1. Modify your app_en.arb, app_es.arb, app_pt_br.arb files

/*
app_en.arb
*/
"adapty_paywalls_locale": "en",

/*
app_es.arb
*/
"adapty_paywalls_locale": "es",

/*
app_pt_br.arb
*/
"adapty_paywalls_locale": "pt-br",

// 2. Extract and use the locale code
final locale = AppLocalizations.of(context)!.adapty_paywalls_locale;
// pass locale code to AdaptyUI.getViewConfiguration or Adapty.getPaywall method

De esta forma tienes control total sobre qué localización se recuperará para cada usuario de tu app.

Implementando las localizaciones: la otra forma

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

final locale = Localizations.localeOf(context).languageCode;
// pass locale code to AdaptyUI.getViewConfiguration or Adapty.getPaywall method

Ten en cuenta que no recomendamos este enfoque por las siguientes 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 bien recrearla tú mismo.
  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 el dispositivo y enviarla a nuestro servidor. Para esa llamada no obtendrás la localización ar-om que buscabas, sino ar, lo cual probablemente no es lo esperado. Aun así, si decides usar este enfoque, asegúrate de haber cubierto todos los casos de uso relevantes.