在 Flutter SDK 中使用本地化和语言区域代码
为什么这很重要
当 Adapty 为流程选择本地化语言,以及你读取自定义付费墙的远程配置时,语言区域代码就会发挥作用。
语言区域代码较为复杂,在不同平台之间可能存在差异,因此 Adapty 在其支持的所有平台上统一采用一套内部标准。了解这一标准,有助于你预测用户最终会收到哪个本地化版本。
Adapty 的语言代码标准
Adapty 的语言代码采用略经修改的 BCP 47 标准:每个代码由小写子标签组成,各子标签之间用连字符分隔。示例:en(英语)、pt-br(葡萄牙语(巴西))、zh(简体中文)、zh-hant(繁体中文)。
语言区域代码匹配
当 Adapty 查找与用户语言区域匹配的本地化内容时,会按以下步骤进行:
- 将语言区域字符串转换为小写,并将所有下划线(
_)替换为连字符(-) - Adapty 查找与完整语言区域代码完全匹配的本地化内容
- 如果未找到匹配项,Adapty 取第一个连字符之前的子字符串(例如
pt-br对应pt),并查找匹配的本地化内容 - 如果仍未找到匹配项,Adapty 返回默认的
en本地化内容
因此,'pt_BR'、pt-BR 和 pt-br 最终都会解析为同一个本地化内容。
实现本地化
在 SDK v4 中,获取流程时无需传入语言区域代码。
- 付费墙编辑工具与流程构建器付费墙:Adapty 会根据设备设置及你在构建器中配置的本地化内容自动解析语言区域。使用
createFlowView渲染流程,无需传入语言区域代码。 - 自定义(远程配置)付费墙:
getFlow会在flow.remoteConfigs中返回所有已配置的本地化内容。每个条目都包含一个locale代码及配置内容(data字符串或已解析的dictionary)。请自行实现回退逻辑,选择与用户匹配的条目:
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 如何对每个远程配置中存储的 locale 代码进行规范化处理。
为什么这很重要
有几种情况下需要用到语言区域代码——例如,当你尝试为当前应用的本地化版本获取正确的付费墙时。
由于语言区域代码比较复杂,且在不同平台之间可能存在差异,我们为所有支持的平台制定了一套内部标准。正因为这些代码较为复杂,理解你究竟向我们的服务器发送了什么内容以获取正确的本地化版本,以及后续会发生什么,就变得尤为重要——这样你才能始终获得预期的结果。
Adapty 语言代码标准
在语言代码方面,Adapty 采用略经修改的 BCP 47 标准:每个代码由小写子标签组成,以连字符分隔。例如:en(英语)、pt-br(葡萄牙语(巴西))、zh(简体中文)、zh-hant(繁体中文)。
语言区域代码匹配
当 Adapty 收到客户端 SDK 发来的语言区域代码请求并开始查找对应的付费墙本地化版本时,流程如下:
- 将传入的语言区域字符串转换为小写,并将所有下划线(
_)替换为连字符(-) - 查找与完整语言区域代码完全匹配的本地化版本
- 如果未找到匹配项,则截取第一个连字符之前的子字符串(例如
pt-br取pt),再次查找匹配的本地化版本 - 如果仍未找到匹配项,则返回默认的
en本地化版本 这样,发送'pt_BR'的 iOS 设备、发送pt-BR的 Android 设备,以及发送pt-br的其他设备,都会得到相同的结果。
实现本地化:推荐方式
如果你正在考虑本地化问题,很可能已经在项目中使用了本地化字符串文件。在这种情况下,我们建议在每个本地化文件中添加一个键值对,用于存储对应语言的 Adapty 语言代码。然后在调用 SDK 时提取该键的值,示例如下:
// 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这样,你就能完全掌控每位用户获取到的本地化内容。
实现本地化的另一种方式
你也可以不为每个本地化显式定义语言区域代码,同样能得到类似(但不完全相同)的结果。这种方式是从平台提供的其他对象中提取语言区域代码,如下所示:
final locale = Localizations.localeOf(context).languageCode;
// pass locale code to AdaptyUI.getViewConfiguration or Adapty.getPaywall method不过,出于以下几点原因,我们不推荐这种方式:
- 在 iOS 上,首选语言和当前语言区域并不相同。如果希望正确选取本地化内容,你需要依赖 Apple 的内置逻辑(使用推荐的本地化字符串文件方案时开箱即用),或者自行重新实现该逻辑。
- 很难预测 Adapty 服务器实际收到的内容。例如,在 iOS 上,设备可能会返回类似
ar_OM@numbers='latn'这样的语言区域标识,并将其发送至我们的服务器。对于这个请求,你得到的不会是预期的ar-om本地化内容,而是ar,这很可能不符合预期。 Should you decide to use this approach anyway — make sure you’ve covered all the relevant use cases.