Friday, February 23, 2018

Force Localize Internal Frameworks like UIKit without App restart

Leave a Comment

I have to add an option of switching language inside the app only. I am just stuck on with localizing internal framworks. Can anyone help me with localization of internal framework like UIKit etc from the app itself without restart. My code works fine but for the case of internal framework requires a restart. Just the internal frameworks are not getting localized.

My current code is :

Create a file named BundleExtension.swift and add the following code to it -

var bundleKey: UInt8 = 0  class AnyLanguageBundle: Bundle {  override func localizedString(forKey key: String,                               value: String?,                               table tableName: String?) -> String {      guard let path = objc_getAssociatedObject(self, &bundleKey) as? String,         let bundle = Bundle(path: path) else {              return super.localizedString(forKey: key, value: value, table: tableName)     }      return bundle.localizedString(forKey: key, value: value, table: tableName)   } }  extension Bundle {  class func setLanguage(_ language: String) {      defer {          object_setClass(Bundle.main, AnyLanguageBundle.self)     }      objc_setAssociatedObject(Bundle.main, &bundleKey,    Bundle.main.path(forResource: language, ofType: "lproj"), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)   } } 

Now whenever you need to change the language call this method :

func languageButtonAction() {     // This is done so that network calls now have the Accept-Language as "hi" (Using Alamofire) Check if you can remove these     UserDefaults.standard.set(["hi"], forKey: "AppleLanguages")     UserDefaults.standard.synchronize()      // Update the language by swaping bundle     Bundle.setLanguage("hi")      // Done to reintantiate the storyboards instantly     let storyboard = UIStoryboard.init(name: "Main", bundle: nil)     UIApplication.shared.keyWindow?.rootViewController = storyboard.instantiateInitialViewController() } 

4 Answers

Answers 1

Check this demo, it will work for you.

Link

Answers 2

your code seems good but what I've tried is...

When change language from app then...

Bundle.setLanguage("fr") UserDefaults.standard.set(["fr"], forKey: kAppleLanguages) UserDefaults.standard.synchronize()  NotificationCenter.default.post(name: NSNotification.Name.init("AppLanguageChangeNotification"), object: nil) 

so whenever language is changed this notification will be fired and the view controller who added observer to this will be notified and according to that language need to be changed.

Add observer

NotificationCenter.default.addObserver(viewController, selector: #selector(self.setLocalization), name: NSNotification.Name.init("AppLanguageChangeNotification"), object: nil) 

Method

@objc fileprivate func setLocalization() {      self.lblProfile.text = NSLocalizedString("lblProfile", comment: "")     self.lbDetails.text = NSLocalizedString("lblDetails", comment: "")     .     . } 

Yes, this is bit log process as you need to have all IBOutles to set the localise text.

Answers 3

It depends on what particular framework you want to localize. This is needed to know where from this framework gets its localizations. For most of the cases it is impossible cause you'll have to hardcode path to localizations file of the framework or know something about framework which breaks one of the framework idea: know less about implementation, all you should know is interface.

To achieve what you want you should have the only source for localizations.

With pods or some other non-system frameworks you can fork them and change it so you could pass your strings to it.

With system libraries it may be impossible cause there is no chance to change it in some way. But all cases I know can be implemented with the help of these system libraries, I'm talking about localized navigation bar buttons, for example. You can make your own button and set its title to whatever you want.

Hope it helps. If not, then you can show the example of what exactly you cannot localize and I'll try to help you.

Answers 4

I faced with the same problem and only solution for me was fully reload all UIViewController

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment