Now I know that apple does not recommend this.
In general, you should not change the iOS system language (via use of the AppleLanguages pref key) from within your application. This goes against the basic iOS user model for switching languages in the Settings app, and also uses a preference key that is not documented, meaning that at some point in the future, the key name could change, which would break your application.
However, this is an application that changing the language on the fly makes sense, just trust me on that. I also know this question was asked here: Changing language on the fly, in running iOS, programmatically. This however is getting old and I was wondering if there are any newer, better, or easier ways to do this. Currently in my app, I have a language choosing screen. Clicking on of the buttons in this view calls the following function with the language the button is associated with:
func changeLang(language: String) {
if language != (currentLang as! String?)! {
func handleCancel(alertView: UIAlertAction!)
{
}
var alert = UIAlertController(title: NSLocalizedString("language", comment: "Language"), message: NSLocalizedString("languageWarning", comment: "Warn User of Language Change Different Than Defaults"), preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler:handleCancel))
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.Default, handler:{ (UIAlertAction) in
NSUserDefaults.standardUserDefaults().setObject([language], forKey: "AppleLanguages")
NSUserDefaults.standardUserDefaults().synchronize()
println(self.currentLang)
let alert = UIAlertView()
alert.title = NSLocalizedString("language", comment: "Sign In Failed")
alert.message = NSLocalizedString("languageChangeNotification", comment: "Notify of language change")
alert.addButtonWithTitle(NSLocalizedString("ok", comment: "Okay"))
alert.show()
self.performSegueWithIdentifier("welcome", sender: AnyObject?())
}))
self.presentViewController(alert, animated: true, completion: {
})
} else {
self.performSegueWithIdentifier("welcome", sender: AnyObject?())
}
}
Example:
@IBAction func english(sender: UIButton) {
changeLang("en")
}
If the user picks a language different than their own, they get a confirmation alert, and then are requested to restart there device. This is what I want to change. It appears that this section of NSUSerDefaults is not synchronized until the app restarts. Evidence:
let currentLang: AnyObject? = NSLocale.preferredLanguages()[0]
println(currentLang)
// Prints english
changeLang("zh-Hans")
println(currentLang)
// Prints english still until restart
The current internationalization system apple has is great, and I plan on using it. However, how can I change the language on the fly, maybe by forcing an update on the NSUSerDefaults?
Edit: I recommend using this library to do this now. Best of luck!