swift - app国际化, 优雅切换
https://www.jianshu.com/p/e5d5fac05b8c
在开发的过程中, 可能你们的app 会有这样的需求, 需要坚持多种语言. 怎么做到不重启app 就更换了语言, 下面我们来讨论下.
首先我们知道, 如果你的app 中需要支持多种语言, 往往我们会选择一个Localizable.strings, 它会一种语言生成一个文件夹, 相当于一个包吧. 所以我们只要做到切换时, 选择对应的语言包就可以了.废话不多说, 我们开始吧.
-
开始国际化
点击项目->PROJECT->Info->Localizations -> + , 添加你想要的语言, 这个谈论中/英-
选择想用本地化的storyboard/xib...
![]()
-
创建Localizable.strings


建议命名为: Localizable
-
选择你新创建的 Localizable.strings , Localize...
xx.png
添加你语言, 最后效果
![]()
-
Localizable.strings 文件中写入
"key" = "value"; 这样的格式. -
storyboard 中生成的
![]()
-
要想生成这种形式, 可以先切换成 , 再切换回来
![]()
-
我们这里主要讨论下怎么切换, 这些简单配置, 就不详细了, 请看最后的Demo.
-
用自己创建的Bundle,想xcode 用自己指定的bundle , 达到切换语言的目的.
import Foundation
class AppSettings: NSObject {
fileprivate static let kSharedSettingsKey = "DefaultUserSettings"
static let shared: AppSettings = {
let appSettings: AppSettings
if let savedData = UserDefaults.standard.object(forKey: AppSettings.kSharedSettingsKey) as? Data,
let defaultSettings = NSKeyedUnarchiver.unarchiveObject(with: savedData) as? AppSettings {
appSettings = defaultSettings
} else {
appSettings = AppSettings()
}
return appSettings
}()
static func saveSharedInstance() {
let data = NSKeyedArchiver.archivedData(withRootObject: AppSettings.shared)
UserDefaults.standard.set(data, forKey: AppSettings.kSharedSettingsKey)
}
enum Language: String {
/// 请注意, 这个命名不是随意的, 是根据你本地的语言包,可以show in finder 看到. en.lproj / zh-Hans.lproj
case Chinese = "zh-Hans"
case English = "en"
var code: String {
return rawValue
}
}
/// 判断手机语言是不是中文
static func localeIsChinese() -> Bool {
if let lang = Locale.preferredLanguages.first {
return lang.hasPrefix("zh") ? true : false ;
} else {
return false
}
}
var language: Language
override init() {
// 第一次初始语言, 看手机是什么语言
language = AppSettings.localeIsChinese() ? .Chinese : .English
super.init()
}
}
private var bundleByLanguageCode: [String: Foundation.Bundle] = [:]
extension AppSettings.Language {
var bundle: Foundation.Bundle? {
/// 存起来, 避免一直创建
if let bundle = bundleByLanguageCode[code] {
return bundle
} else {
let mainBundle = Foundation.Bundle.main
if let path = mainBundle.path(forResource: code, ofType: "lproj"),
let bundle = Foundation.Bundle(path: path) {
bundleByLanguageCode[code]








