Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change localization language without restart application swift4?

Hello iam trying to change localization string file with out restart the application , after change the language i need to restart the application to see new language this is how i am changing the application language but i need to restart application to see change using this library https://github.com/marmelroy/Localize-Swift i need to set all label values programmatically which is headache i don't want to this like this way

var selectedLanguage:Languages
let preferredLanguage : String = Bundle.main.preferredLocalizations.first!
print("app langugage \(preferredLanguage)")
if(preferredLanguage == "en") {
    // Localize.setCurrentLanguage("de")
    selectedLanguage = .de
    LanguageManger.shared.setLanguage(language: selectedLanguage)
}
else {
    // Localize.setCurrentLanguage("en")
    selectedLanguage = .en
    LanguageManger.shared.setLanguage(language: selectedLanguage)

}

LanguageManger.shared.setLanguage(language: selectedLanguage)

// return to root view contoller and reload it

let transition: UIViewAnimationOptions = .transitionFlipFromLeft
let rootviewcontroller: UIWindow = ((UIApplication.shared.delegate?.window)!)!
        rootviewcontroller.rootViewController = self.storyboard?.instantiateViewController(withIdentifier: "rootnav")
        let mainwindow = (UIApplication.shared.delegate?.window!)!
        mainwindow.backgroundColor = UIColor(hue: 0.6477, saturation: 0.6314, brightness: 0.6077, alpha: 0.8)
        UIView.transition(with: mainwindow, duration: 0.55001, options: transition, animations: { () -> Void in
        }) { (finished) -> Void in

}
like image 477
Jhony Avatar asked Jul 03 '18 11:07

Jhony


People also ask

How do I force a program language programmatically without breaking the app?

Every time at app launch you have to set the last app language code to preserve the language setting and for this you have to save language code in the other UserDefaults key.

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.

How do I change the language on Swift 4?

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. Save this answer.

How do I reopen an app in Swift?

You can't restart the app. However, you can kill it using exit(0) and hoping that the user will launch it again.


1 Answers

Make a new class NSBundle+Language.h, NSBundle+Language.m. And don't forget to add bridging header.

NSBundle+Language.h

#import <Foundation/Foundation.h>

@interface NSBundle (Language)
+(void)setLanguage:(NSString*)language;
@end

NSBundle+Language.m

#import "NSBundle+Language.h"

#import <objc/runtime.h>

static const char _bundle=0;

@interface BundleEx: NSBundle
@end

@implementation BundleEx
-(NSString*)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
{
    NSBundle* bundle=objc_getAssociatedObject(self, &_bundle);
    return bundle ? [bundle localizedStringForKey:key value:value table:tableName]: [super localizedStringForKey:key value:value table:tableName];
}
@end

@implementation NSBundle (Language)

+(void)setLanguage:(NSString*)language
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
                  {
                      object_setClass([NSBundle mainBundle],[BundleEx class]);
                  });
    objc_setAssociatedObject([NSBundle mainBundle], &_bundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]]: nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end

After this use this language manager to change the language:-

class LanguageManager: NSObject {
    //MARK: Set language preference

    class func setSelectedLanguage(dictionary: [String: String]) {
        let userDefaults = UserDefaults.standard
        userDefaults.set(dictionary, forKey: kSelectedLanguageDetails)
        userDefaults.synchronize()
    }

    class  func getSelectedLanguage() ->  [String: String]? {

        let userDefaults = UserDefaults.standard
        return userDefaults.value(forKey: kSelectedLanguageDetails) as?  [String: String]
    }

    class func getSelectedLangaugeCode() -> String{
        if let selectedLanguageDetails = LanguageManager.getSelectedLanguage() {
            if let languageCode =  selectedLanguageDetails[LocalizationKeys.kLanguageCode.rawValue]  {
                Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
                return languageCode.lowercased()
            }
            else {
                let languageDetails = [LocalizationKeys.kLanguageCode.rawValue:"EN", LocalizationKeys.kLanguageName.rawValue:"English", LocalizationKeys.kLanguageID.rawValue:"1"]
                LanguageManager.setSelectedLanguage(dictionary: languageDetails)
                if let languageCode =  languageDetails[LocalizationKeys.kLanguageCode.rawValue] {
                    Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
                    return languageCode.lowercased()
                }
            }
        }
        else {
            let languageDetails = [LocalizationKeys.kLanguageCode.rawValue:"EN", LocalizationKeys.kLanguageName.rawValue:"English", LocalizationKeys.kLanguageID.rawValue:"1"]
            LanguageManager.setSelectedLanguage(dictionary: languageDetails )
            if let languageCode =  languageDetails[LocalizationKeys.kLanguageCode.rawValue] {
                Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
                return languageCode.lowercased()
            }
        }
        return "en"
    }

    /// Checks for the Language preferences selected by user
    class func checkLanguagePreferenceAndSetToDefaults() {
        if let selectedLanguageDetails = LanguageManager.getSelectedLanguage() {
            if let languageCode =  selectedLanguageDetails[LocalizationKeys.kLanguageCode.rawValue]  {
                Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
            }
            else {
                let languageDetails = [LocalizationKeys.kLanguageCode.rawValue:"EN", LocalizationKeys.kLanguageName.rawValue:"English", LocalizationKeys.kLanguageID.rawValue:"1"]
                LanguageManager.setSelectedLanguage(dictionary: languageDetails)
                if let languageCode =  languageDetails[LocalizationKeys.kLanguageCode.rawValue] {
                    Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
                }
            }
        }
        else {
            let languageDetails = [LocalizationKeys.kLanguageCode.rawValue:"EN", LocalizationKeys.kLanguageName.rawValue:"English", LocalizationKeys.kLanguageID.rawValue:"1"]
            LanguageManager.setSelectedLanguage(dictionary: languageDetails )
            if let languageCode =  languageDetails[LocalizationKeys.kLanguageCode.rawValue] {
                Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
            }
        }
    }


    //MARK: Get Language Code

    /// Return apple specific language code
    ///
    /// - parameter languageCode: language code string
    ///
    /// - returns: apples language code
    static func getAppleLanguageCode(languageCode:String) -> String{
        switch languageCode.lowercased() {
        case "en":
            return "en"
        case "es":
            return "es"
        case "fr":
            return "fr"
        case "de":
            return "de"
        case "it":
            return "it"

        default:
            return languageCode
        }
    }
}

Define the language options as bellow:-

let KlanguageOptionArray: [[String:String]] = [
    [
        "LanguageCode": "EN",
        "Name": "English",
        "LanguageID": "1"
        ],
    [
        "LanguageCode": "ES",
        "Name": "Español",
        "LanguageID": "2"
        ],
    [
        "LanguageCode": "FR",
        "Name": "Français",
        "LanguageID": "3"
        ],
    [
        "LanguageCode": "DE",
        "Name": "Deutsch",
        "LanguageID": "4"
        ],
    [
        "LanguageCode": "IT",
        "Name": "Italiano",
        "LanguageID": "5"
        ]
]

Change the selected language with bellow code

let selectedLanguageDetails = self.languageOptionArray[indexPath.row]
LanguageManager.setSelectedLanguage(dictionary: selectedLanguageDetails)
if let languageCode = selectedLanguageDetails[LocalizationKeys.kLanguageCode.rawValue] {
            Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
      NotificationCenter.default.post(name: NSNotification.Name(rawValue: NotificationCenterTypes.ReloadTableOnLanguageChangeNotification), object: nil)
   }

And don't forget to add this on every launch

if let selectedLanguageDetails = LanguageManager.getSelectedLanguage() {
    if let languageCode =  selectedLanguageDetails[LocalizationKeys.kLanguageCode.rawValue]  {
        Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
    }
    else {
    }
}

Hope this helps you

like image 147
Hussain Chhatriwala Avatar answered Sep 27 '22 18:09

Hussain Chhatriwala