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

SwiftUI框架中插值字符串本地化占位符未替换问题

SwiftUI 框架错误本地化插值占位符不替换问题解决方法

问题场景

在SwiftUI iOS应用中,通过自定义框架与App Extension共享代码,框架内定义的CustomError枚举带有需本地化的message参数。非插值字符串翻译正常,但传递插值字符串时,翻译后的占位符无法被对应值替换(比如doStuff()抛出的错误)。环境为Xcode 16.2,测试iOS 17.4、18.1、18.2均存在该问题。

核心原因

  1. 本地化字符串占位符格式与代码传递的参数不匹配,或未通过正确方式处理插值
  2. 框架本地化文件未正确配置,导致App Extension无法加载对应资源
  3. 错误枚举中直接传递预插值字符串,而非在本地化逻辑中处理参数替换

解决步骤

1. 规范本地化字符串与参数匹配

确保.strings文件中的占位符格式和代码参数类型一致:

  • 字符串类型用%@,整数用%d,浮点数用%f
  • 示例本地化字符串(英文):
    "error.invalid_field" = "Field %@ contains invalid content";
    "error.max_limit" = "Maximum allowed value is %d";
    

2. 正确实现错误枚举的本地化逻辑

不要直接将插值后的字符串传入枚举,而是将参数传递给枚举,在errorDescription中完成本地化和插值:

enum CustomError: LocalizedError {
    case invalidField(name: String)
    case maxLimitReached(value: Int)
    case general(message: String)

    var errorDescription: String? {
        switch self {
        case .invalidField(let name):
            return String(format: NSLocalizedString("error.invalid_field", bundle: .module, comment: "Invalid field error"), name)
        case .maxLimitReached(let value):
            return String(format: NSLocalizedString("error.max_limit", bundle: .module, comment: "Max limit error"), value)
        case .general(let message):
            return NSLocalizedString(message, bundle: .module, comment: "")
        }
    }
}

抛出错误时直接传递原始参数:

// 正确用法
throw CustomError.maxLimitReached(value: 10)

3. 确保框架本地化资源被正确引用

  • 在框架的Build Settings中,确认Localization列表包含目标语言
  • 检查本地化文件的Target Membership,勾选框架目标和所有需要共享的App Extension目标
  • 加载本地化字符串时必须指定框架的Bundle.module,避免使用默认主bundle(App Extension无法访问主App的bundle资源)

4. 验证App Extension的本地化配置

在App Extension的Info.plist中添加CFBundleLocalizations键,列出支持的语言:

<key>CFBundleLocalizations</key>
<array>
    <string>en</string>
    <string>zh-Hans</string>
</array>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 20:44:54