Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force NSLocalizedString to use a specific language using Swift

With swift, how can I force my app to read data from a specific Localizable.strings.

I put this in didFinishLaunchingWithOptions before instantiate the ViewController but it still show me the App in English.

NSUserDefaults.standardUserDefaults().removeObjectForKey("AppleLanguages")
NSUserDefaults.standardUserDefaults().setObject("fr", forKey: "AppleLanguages"   
NSUserDefaults.standardUserDefaults().synchronize()

And I tried to pass an Array for the "AppleLanguages" key like this but it still doesn't work:

NSUserDefaults.standardUserDefaults().setObject(["fr"], forKey: "AppleLanguages"

And once this is done, can I call this inside the App and take the changes in consideration without restarting the App?

like image 683
sazz Avatar asked Jan 10 '15 17:01

sazz


People also ask

How does NSLocalizedString work?

NSLocalizedString is a Foundation macro that returns a localized version of a string. It has two arguments: key , which uniquely identifies the string to be localized, and comment , a string that is used to provide sufficient context for accurate translation.

How do I change the button click language in Swift?

Click on the + button under the localizations section. You will see the following list of applications. Select the language you want to add into your app. After selecting the language, following popup will be appeared.

How do I change the language in Swift?

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.


3 Answers

It's not possible to change app's language immediately by changing the value of AppleLanguages. It requires restarting the app before the change takes effect.

It seems that your problem is accessing the localization strings of different languages rather than changing the app's language, right? If you want your app to support multiple languages, you can just provide the translations and rely on settings.app for the actual change.

If you want to access the localization strings from other than currently used localization, you need to get access to the proper translations bundle. And then just query that bundle for the translations. The following piece of code should do the trick.

let language = "en"
let path = Bundle.main.path(forResource: language, ofType: "lproj")
let bundle = Bundle(path: path!)
let string = bundle?.localizedStringForKey("key", value: nil, table: nil)
like image 52
Markus Avatar answered Sep 28 '22 09:09

Markus


With NSLocalizedString you can specify the bundle.

let language = "fr"
let path = Bundle.main.path(forResource: language, ofType: "lproj")!
let bundle = Bundle(path: path)!
let localizedString = NSLocalizedString(key, bundle: bundle, comment: "")

Or with a bundle, you may also call localizedStringForKey:value:table: directly too.

like image 31
samwize Avatar answered Sep 28 '22 08:09

samwize


@Radu I also made this working for XCUITests thanks to @Markus' original answer :

You can specify explicitly the path to your MainBundle, it will only work on your Mac with the Simulator, but it is often used in continuous integration platforms so this might be acceptable :

let language: String = "en"
let path = "/Users/{username}/{path_to_your_project}/\(language).lproj"
let bundle = Bundle(path: path)
let string = bundle?.localizedString(forKey: "key", value: nil, table: nil)
like image 34
cdescours Avatar answered Sep 28 '22 07:09

cdescours