0

I have Googled this for hours but could find no advice for the following problem (using Swift).

I have seen in many apps an option to select the language from inside the app like this:

Choose your language screen
(source: unity3d.com)

I would like to achieve something similar, but am having trouble implementing it. I have localized my app and have my Localizable.strings files all set up. I'd imagine it has something to do with storing the language selected in NSUserDefaults, but how can I make the app use the appropriate Localizable.strings file once a language has been chosen? Or is that the wrong way to approach it?

How have others successfully implemented this feature in Swift?

Community
  • 1
  • 1
Eatton
  • 455
  • 4
  • 20
  • Maintain a plist file with all these languages as you have already done localization just load the plist with the language selected by user. – Rein rPavi Dec 17 '15 at 14:37
  • Thanks for your reply. Could you go into a bit more detail please? So say I had a variable called languageChosen and set it to "French" for example, how would I use the plist file to call the correct Localizable.strings file? – Eatton Dec 17 '15 at 14:52
  • Just load the plist NSString *path = [[NSBundle mainBundle] bundlePath]; NSString *customPlistPath = [path stringByAppendingPathComponent:@"French.plist"]; NSDictionary *plistData = [NSDictionary dictionaryWithContentsOfFile:customPlistPath]; – Rein rPavi Dec 17 '15 at 15:07
  • Ah I see, thank you. Using this method though, I assume I can't set text on labels directly using storyboard. I will have to set every label's text programmatically using the relevant plist, is that correct? – Eatton Dec 17 '15 at 16:31

1 Answers1

2

I've already faced this issue on one of my project and found one solution :

When the user select a language from a list, post a NSNotification. All your UIViewController subclass must register to this notification and change the labels value according to the new language selected.

You can use the localized strings in order to set the labels, but NSLocalizedString(...) shouldn't be called since it's relying on the device language which is different from the application language.

You can find my implementation of a custom localisator on Github, available both on Swift and objective-C.

Michaël Azevedo
  • 3,874
  • 7
  • 31
  • 45
  • Thank you for this. I just downloaded it and had a quick play, it looks like a really good solution! I think I will try to get this working in my project as it makes use of existing Localizable.strings files. I will come back and mark this answer as correct if it solves my problem. Quick question though - my app is already live in the app store. If I add localization using your method, will it affect the functionality for existing users of my app? It's a game with scores and progress saved locally on the device using a plist - will there be any issues? – Eatton Dec 17 '15 at 17:04
  • I used it in a production app which previously used localizable strings and didn't get any issue during the transition : since the default value of this custom localisator is "Device Language", there is no visible change for the user. – Michaël Azevedo Dec 18 '15 at 00:02
  • This solution is perfect for me, it's a great piece of code that's easy to integrate into an existing project. I got it working effortlessly. Thanks so much for sharing Michaël. :-) – Eatton Dec 19 '15 at 01:09
  • I'm glad to know it helped :) – Michaël Azevedo Dec 19 '15 at 10:18
  • I am getting an error in a line of your code in Swift 3.0. `func receiveLanguageChangedNotification(_ notification:Notification) { if notification.name == kNotificationLanguageChanged { configureViewFromLocalisation() } } ` The error is: Binary operator '==' cannot be applied to operands of type 'Notification.Name' (aka 'NSNotification.Name') and 'String'. Please could you let me know how to fix this? – Eatton Oct 06 '16 at 17:28
  • @Eatton : I'm looking at it right now, never tried it on Swift 3.0 ! – Michaël Azevedo Oct 07 '16 at 06:24
  • @Eatton A new branch was created for Swift 3.0, look can try it now :) – Michaël Azevedo Oct 07 '16 at 07:02
  • Brilliant, thanks! :-) It works perfectly, I appreciate you taking the time to update the code. – Eatton Oct 07 '16 at 16:01