NSLocale.current.language返回错误值、iPhone语言未同步及获取ISO 639-1码问题
嗨,我来帮你解决这个问题~
首先明确:你的应用是否支持西班牙语,和系统语言变化后能否获取到最新语言设置完全无关。你遇到的NSLocale.current.language没同步的问题,是因为这个API的特性导致的,不是App本地化支持的锅。
为什么NSLocale.current.languageCode不会同步更新?
在iOS中,Locale.current(也就是你用的NSLocale.current)是App启动时初始化的,它会保持App启动时的系统语言设置,在App运行期间,即使用户更改了系统语言,这个值也不会自动更新,除非你重启App或者手动触发刷新。
但相反,Locale.preferredLanguages(对应你的NSLocale.preferredLanguages)是会实时反映系统最新的首选语言列表的——在iOS 13及以上版本,当App从后台回到前台时,这个列表会自动更新;如果是更早的系统,你可以通过监听localeDidChange通知来捕获语言变化事件。
正确获取ISO 639-1两位代码的方法
你的最终需求是获取用户首选语言的ISO 639-1两位代码,推荐用下面的方式(Swift中更推荐使用Locale而非NSLocale,API更贴合Swift风格):
func getPreferredLanguageISOCode() -> String? { // 获取用户首选语言列表的第一个元素(优先级最高的语言) guard let firstPreferredLang = Locale.preferredLanguages.first else { return nil } // 将语言标识符转换为Locale对象,提取languageCode(就是ISO 639-1两位代码) let locale = Locale(identifier: firstPreferredLang) return locale.languageCode } // 使用示例 if let isoCode = getPreferredLanguageISOCode() { print("用户首选语言ISO 639-1代码: \(isoCode)") // 比如西班牙语会输出"es" }
额外提示:监听系统语言变化
如果你需要在用户更改系统语言后,实时更新App内的语言相关逻辑,可以注册通知监听:
// 在合适的地方(比如ViewController的viewDidLoad)注册通知 NotificationCenter.default.addObserver(forName: .localeDidChange, object: nil, queue: .main) { [weak self] _ in // 在这里重新获取最新的语言代码并处理 if let newISOCode = self?.getPreferredLanguageISOCode() { print("系统语言已更新,新的ISO代码: \(newISOCode)") // 这里可以更新UI、重新加载本地化资源等 } } // 记得在deinit中移除监听 deinit { NotificationCenter.default.removeObserver(self) }
补充一句:哪怕你的App没有西班牙语的本地化资源,Locale.preferredLanguages依然会把西班牙语放在列表里,你完全可以正常获取到它的ISO代码。
内容的提问来源于stack exchange,提问作者Jeremiah
相关产品推荐
相关产品推荐

