如何复用LocalizedStringKey属性实现带占位符的本地化字符串?
问题背景
我的Localizable.strings包含以下键值对:
"turn_off_feature_format" = "Turn off %@"; "feature_1_title" = "Feature 1"; "feature_2_title" = "Feature 2";
注:这些键需在其他平台及旧UIKit代码中复用,无法重命名
为避免硬编码字符串重复,我给LocalizedStringKey做了扩展,把键定义成静态属性:
extension LocalizedStringKey { static let feature1Title = Self("feature_1_title") static let feature2Title = Self("feature_2_title") }
使用时直接写Text(.feature1Title)即可。
但处理带占位符的本地化字符串(比如turn_off_feature_format)时遇到麻烦——当前实现需要重复硬编码"turn_off_feature_format",能不能复用已定义的LocalizedStringKey属性来实现turnOffFeature1和turnOffFeature2?或者有没有更优的解决方案?
解决方案1:统一维护本地化键常量(最稳妥)
先把所有本地化键抽成枚举常量,再基于这些常量定义LocalizedStringKey属性,从根源避免硬编码重复:
// 统一管理所有本地化键 private enum LocalizationKey: String { case turnOffFeatureFormat = "turn_off_feature_format" case feature1Title = "feature_1_title" case feature2Title = "feature_2_title" } // 基于枚举扩展LocalizedStringKey extension LocalizedStringKey { static let turnOffFeatureFormat = Self(LocalizationKey.turnOffFeatureFormat.rawValue) static let feature1Title = Self(LocalizationKey.feature1Title.rawValue) static let feature2Title = Self(LocalizationKey.feature2Title.rawValue) // 生成带特征名称的"关闭"文本 static func turnOffFeature(_ feature: LocalizationKey) -> LocalizedStringKey { Self(String(format: LocalizationKey.turnOffFeatureFormat.rawValue, feature.rawValue)) } } // 使用示例 Text(.turnOffFeature(.feature1Title))
所有键只写一次,既兼容现有UIKit代码,又能复用格式串生成目标文本。
解决方案2:复用已定义的LocalizedStringKey属性
如果不想额外维护枚举,可以通过Mirror提取LocalizedStringKey的原始key值,复用已有的静态属性:
extension LocalizedStringKey { static let turnOffFeatureFormat = Self("turn_off_feature_format") static let feature1Title = Self("feature_1_title") static let feature2Title = Self("feature_2_title") // 提取LocalizedStringKey对应的原始key字符串 private var rawKey: String? { Mirror(reflecting: self).children.first?.value as? String } // 生成带特征名称的"关闭"文本 static func turnOffFeature(_ featureKey: Self) -> LocalizedStringKey { guard let featureRawKey = featureKey.rawKey, let formatRawKey = turnOffFeatureFormat.rawKey else { return Self("Turn off Unknown Feature") // 降级处理,避免崩溃 } return Self(String(format: formatRawKey, featureRawKey)) } } // 使用示例 Text(.turnOffFeature(.feature1Title))
这种方法不用额外维护枚举,但依赖Mirror反射,性能影响在本地化场景下可忽略。
更优方案:SwiftUI专属封装(简化调用)
如果只在SwiftUI中使用,可以直接给Text写扩展,让调用更简洁:
private enum LocalizationKey: String { case turnOffFeatureFormat = "turn_off_feature_format" case feature1Title = "feature_1_title" case feature2Title = "feature_2_title" } extension Text { static func turnOffFeature(_ feature: LocalizationKey) -> Text { Text(LocalizationKey.turnOffFeatureFormat.rawValue) .interpolated(with: Text(feature.rawValue)) } } // 使用示例 Text.turnOffFeature(.feature1Title)
直接生成拼接好的本地化文本,无需手动处理占位符,代码更直观。
内容的提问来源于stack exchange,提问作者lazarevzubov
相关产品推荐
相关产品推荐

