Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting "AppleLanguages" doesn't change app language

Tags:

ios

swift

ios8

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?

like image 801
1110 Avatar asked Jun 10 '15 07:06

1110


People also ask

How do I change the language in Swift app?

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.

How do I change the button click language in Swift?

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.

What is locale Swift?

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.


1 Answers

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
enter image description here
6. Then Every time you need to localize your app, you only need to call. Utils.setLanguage({LanguageType})

like image 90
Neo Nguyen Avatar answered Sep 18 '22 12:09

Neo Nguyen