You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift获取iOS设备系统语言 真机始终返回en_US问题排查

问题成因
  • 核心逻辑缺陷:Locale.preferredLanguages返回的是符合BCP 47标准的完整语言标签,真实用户的系统默认语言通常会携带地区后缀,例如乌克兰地区用户返回uk-UA、克罗地亚地区用户返回hr-HR。原有代码直接拿完整标签字符串匹配枚举rawValue(枚举中乌克兰语、克罗地亚语的rawValue是不带后缀的"uk"、"hr"),匹配失败后直接回退到默认英文。
  • 测试场景偏差:本地手动切换系统语言时,选择的是无地区后缀的通用语言选项,标签格式和真实用户的默认配置不一致,因此本地测试正常、线上用户异常。
  • 代码疏漏:availableLanguages数组声明了土耳其语、荷兰语、瑞典语三个支持项,但Languages枚举中未定义对应的case,会直接触发编译错误。
修复方案

调整匹配逻辑,不要直接用完整语言标签做硬匹配,按分层逻辑匹配:

  1. 优先尝试匹配完整语言标签,覆盖en-GB这类带地区的英语变体场景
  2. 完整标签匹配失败时,提取标签中的纯语言代码做二次匹配,覆盖uk-UA、hr-HR这类带地区后缀的通用语言场景
  3. 补全枚举中缺失的语言case
  4. 兼容不同iOS版本的语言代码提取逻辑

修改后可正常运行的代码如下:

extension Locale {
    static var currentLanguage: Languages {
        let defaultLanguage = Languages.English_US
        
        guard let preferredLanguage = preferredLanguages.first else {
            return defaultLanguage
        }
        
        // 兼容高低版本iOS提取纯语言代码
        let languageCode: String?
        if #available(iOS 16, *) {
            languageCode = Locale(identifier: preferredLanguage).language.languageCode?.identifier
        } else {
            languageCode = preferredLanguage.split(separator: "-").first.map(String.init)
        }
        
        guard let code = languageCode else {
            return defaultLanguage
        }
        
        // 先匹配完整语言标签,再匹配纯语言代码
        if let fullMatch = Languages(rawValue: preferredLanguage), availableLanguages.contains(fullMatch) {
            return fullMatch
        }
        
        if let codeMatch = Languages(rawValue: code), availableLanguages.contains(codeMatch) {
            return codeMatch
        }
        
        return defaultLanguage
    }
}

/// 应用支持的语言列表
let availableLanguages : [Languages] = [.English_US, .Turkish, .Dutch, .Swedish, .Croatian, .Ukrainian]

enum Languages: String, CaseIterable, Codable, Equatable, Comparable {
    case Croatian              = "hr"
    case English_US            = "en"
    case English_UK            = "en-GB"
    case English_Australian    = "en-AU"
    case English_Canadian      = "en-CA"
    case French                = "fr"
    case French_Canadian       = "fr-CA"
    case Ukrainian             = "uk"
    // 补全之前缺失的枚举项
    case Turkish               = "tr"
    case Dutch                 = "nl"
    case Swedish               = "sv"
}

额外校验:需确保项目Info.plist中CFBundleLocalizations字段正确填写了所有应用支持的语言代码,否则系统会自动过滤掉未声明的语言,导致preferredLanguages返回结果不符合预期。

内容的提问来源于stack exchange,提问作者ursan526

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 19:12:18