Widget 国旗:为何 ISO 国家代码优于依赖语言环境的名称
Bug 描述
iOS widget 以两种方式显示地区信息:旗帜表情符号和国家名称文本。在英文语言环境(en-US、en-GB)下,两者正确匹配。在泰语、马来语和越南语语言环境下,名称文本正确翻译了,但旗帜显示的是错误的地区。
根本原因
旗帜是从语言环境标识符生成的,而不是从 ISO 国家代码生成的。代码使用了 Locale.current.regionCode,它返回设备语言环境的地区,而不是应用要显示的地区。
当设备语言环境是泰语(th-TH)时,Locale.current.regionCode 返回"TH"。代码使用这个来生成泰国旗帜,但显示的名称是一个不同的地区——因为名称来自不同的数据源,该数据源使用了正确的目标地区。
为什么 ISO 代码是正确的方法
ISO 3166-1 alpha-2 国家代码是明确的:"SG"总是指新加坡,无论用户的语言环境是什么。语言环境标识符是上下文相关的:同一个语言环境标识符在不同上下文中可能有不同的含义。
规则:使用 ISO 国家代码存储和传递地区标识,在显示层使用语言环境进行名称翻译。不要将这两者混合。
修复
修复很简单:将地区数据模型从语言环境标识符更改为 ISO 3166-1 alpha-2 代码,并仅将语言环境用于将代码翻译为显示名称:
// 之前 - 脆弱的
let flagEmoji = flag(from: Locale.current.regionCode)
// 之后 - 正确的
let isoCode = region.isoCode // 例如 "SG"
let flagEmoji = flag(from: isoCode)
let displayName = Locale.current.localizedString(forRegionCode: isoCode)