示例代码🔗https://github.com/gewill/BlogCodes/tree/main/Localizable%20in%20SwiftPM
在处理SwiftPM中本地化时,尝试了几种方案。先说结论Rswift preferredLanguage方案最佳。
方案一:Local 在SwiftUI中使用local可行,但是在SwiftPM会被宿主应用中覆写。不过也是小问题,只要命名规范,按照模块页面功能前缀来的话,一般也不会出现key重复的问题。
这里也是用到了Rswift自动生成的key
,避免复制粘贴字符串类型的key
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Section { Text ("Change locale" ).font(.title) Text ("Will be overwrite by host app!" ).foregroundColor(.pink) Button (action: { viewModel.locale = Locale (identifier: Language .en.rawValue) }, label: { Text ("Change locale english" ) }) Button (action: { viewModel.locale = Locale (identifier: Language .zh_Hans.rawValue) }, label: { Text ("Change locale chinese simplified" ) }) Text (LocalizedStringKey (R .string.localizable.hello_world.key.description)) } header: { Text ("Change locale" ) } .environment(\.locale, viewModel.locale)
方案二:Rswift preferredLanguage 目前是比较完善的方案。配合 AppLocale
可以全局切换语言。
利用Rswift可处理key和bundle的问题,还优化了SwiftUI.Text
的使用体验,直接使用init
即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class AppLocale { let preferredLanguage = CurrentValueSubject <Language , Never >(.en) var preferredString: _R.string { R .string(preferredLanguages: [preferredLanguage.value.rawValue]) } static var shared = AppLocale () private init () {} } Section { Text ("Preferred Languages \(viewModel.preferredLanguage.displayTitle) " ) Picker ("Preferred Languages" , selection: $viewModel .preferredLanguage) { ForEach (Language .allCases) { Text ($0 .displayTitle) } } .pickerStyle(.segmented) Text (AppLocale .shared.preferredString.localizable.hello_world) } header: { Text ("Change R.string Preferred Languages" ) }
最轻量级集成方式在ViewModel订阅AppLocale.shared.preferredLanguage
,更新self.objectWillChange.send()
,即可响应语言切换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class HomeViewModel : ObservableObject { init () { AppLocale .shared.preferredLanguage .removeDuplicates() .sink(receiveValue: { _ in guard let self else { return } self .objectWillChange.send() }) .store(in: & cancelables) } } struc HomeView : View { @StateObject var viewModel = HomeViewModel () var body: some View { Text (AppLocale .shared.preferredString.localizable.hello_world) } }
可用,但是仅支持 iOS16+
。有个小坑SwiftPM集成时,官方教程的有错误,正确的git地址为:
1 2 3 4 .package(url: "https://github.com/liamnichols/xcstrings-tool.git" , from: "0.1.0" ) .package(url: "https://github.com/liamnichols/xcstrings-tool-plugin.git" , from: "0.1.0" )
具体参考官方的示例:https://github.com/liamnichols/xcstrings-tool-demo