I am trying to implement a function that can change app language.
I tried to set it like this:
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("de", forKey: "AppleLanguages")
And after app restart language is still 'system default'.
Now I test different languages by setting Scheme > Application Language > language
.
But is it possible to user click a button and after restart to see picked language?
Also what is the proper way to do this to avoid changing language on restart?
There is a language setting within the "Settings" app (a system app), and there the user can set the language. All installed apps will use this language setting.
Click on iOS->App/Single View App->Next. Name your project and select the language as Swift. Select a desired location and click on Create. To start with Localization, click on your Project Name -> go to Info Tab -> Under Localizations, click on the '+' button.
The Locale object in Swift is used to retrieve some pieces of information on the Locale settings of the user. These settings can depend on the general set up of the device or on the settings for a specific app.
This solution work for me:
1. Create an extension of Bundle
import Foundation
class L012Localizer: NSObject {
class func DoTheSwizzling() {
MethodSwizzleGivenClassName(cls: Bundle.self, originalSelector: #selector(Bundle.localizedString(forKey:value:table:)), overrideSelector:
#selector(Bundle.specialLocalizedString(key:value:table:)))
}
}
extension Bundle {
@objc func specialLocalizedString(key: String, value: String?, table tableName: String?) -> String {
let currentLanguage = Utils.currentLanguage().rawValue
var bundle = Bundle();
if currentLanguage != "" , let _path = Bundle.main.path(forResource: currentLanguage, ofType: "lproj") {
bundle = Bundle(path: _path)!
} else {
let _path = Bundle.main.path(forResource: "Base", ofType: "lproj")!
bundle = Bundle(path: _path)!
}
return (bundle.specialLocalizedString(key: key, value: value, table: tableName))
}
}
func MethodSwizzleGivenClassName(cls: AnyClass, originalSelector: Selector, overrideSelector: Selector){
let origMethod: Method = class_getInstanceMethod(cls, originalSelector)!;
let overrideMethod: Method = class_getInstanceMethod(cls, overrideSelector)!;
if (class_addMethod(cls, originalSelector, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
class_replaceMethod(cls, overrideSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
} else {
method_exchangeImplementations(origMethod, overrideMethod);
}
}
2. Call DoTheSwizzling in AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
L012Localizer.DoTheSwizzling()
return true
}
3. Create Language Utils
class Utils: NSObject {
class func setLanguage(_ lang: LanguageType) {
UserDefaults.standard.set([lang.rawValue], forKey: "AppleLanguages")
}
class func currentLanguage() -> LanguageType {
if let langs = UserDefaults.standard.object(forKey: "AppleLanguages") as? [String], let currentLang = langs.first {
return LanguageType(rawValue: currentLang) ?? .english
}
return .english
}
}
4. Create Language Type
enum LanguageType: String {
case english = "en"
case korea = "ko"
case vietnamese = "vi-VN"
func toString() -> String {
switch self {
case .korea:
return "Korea".localized
case .vietnamese:
return "Vietnamese".localized
default:
return "English".localized
}
}
}
5. Remember that you have to config Application Language in Scheme to SystemLanguage
6. Then Every time you need to localize your app, you only need to call. Utils.setLanguage({LanguageType})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With