Swift开发中如何从localizedString反向获取对应原始语言代码?
结论
系统没有提供公开的原生API支持「本地化语言名称反向转语言代码」的能力,所有官方Locale相关接口仅实现了「语言/区域代码转用户可读本地化名称」的单向转换,不存在你要的优雅原生逆向方案。
为什么不建议硬做逆向转换
本地化展示名本身就是纯UI层的展示内容,天生不适合作为数据传递、匹配的载体,硬做逆向会有很多不可控问题:
- 展示名随系统语言变化:同样是英语,在中文系统下显示
英文、日文系统下显示英語、西语系统下显示Inglés,没有固定匹配值 - 系统版本兼容性差:不同版本的iOS/macOS对部分语言的本地化翻译可能微调,会直接导致匹配失效
- 存在重名冲突:部分语言的地区变体会生成完全相同的本地化名称,无法唯一映射到原始代码
- 性能损耗:如果用遍历全量语言代码匹配的曲线方案,每次转换都要遍历数百个系统语言标识,造成无必要的性能浪费
最优实现方案
根本不需要做逆向转换,直接调整Picker的绑定逻辑即可:数据层永远存原始语言代码,仅在UI渲染时做单向的代码转展示名操作,这也是SwiftUI Picker组件的标准用法,改完的代码比你现在的实现更简洁,稳定性拉满:
@AppStorage("language") var language: String = "en" Picker("settingsTabGeneralSectionHeader".localized(), selection: $language) { ForEach(Bundle.main.localizations, id: \.self) { langCode in Text(Locale.current.localizedString(forLanguageCode: langCode) ?? langCode) .tag(langCode) } }
代码说明:
- 直接把
Picker的选中值绑定到你存偏好的@AppStorage变量上,不需要额外定义@State存展示名 - 循环的元素是原始语言代码,仅在
Text初始化时做正向的本地化名称转换 - 通过
.tag(langCode)明确告诉Picker当前选项的选中值为原始语言代码,选中后直接自动写入UserDefaults,完全不需要onChange回调做额外处理 - 对本地化失败的情况做了兜底,直接展示原始语言代码,避免强制解包带来的崩溃
仅做原理参考的逆向实现(禁止生产环境使用)
如果你只是好奇怎么用系统能力曲线实现逆向,唯一的方法是遍历全量系统语言标识,逐个生成本地化名称做匹配,但是再次强调,这个方案鲁棒性极差,绝对不要用到线上:
func languageCode(fromLocalizedName targetName: String) -> String? { Locale.availableIdentifiers .compactMap { identifier -> String? in guard let code = Locale(identifier: identifier).languageCode, let localizedName = Locale.current.localizedString(forLanguageCode: code), localizedName == targetName else { return nil } return code } .first }
内容的提问来源于stack exchange,提问作者gherblino
相关产品推荐
相关产品推荐

