How to force NSLocalizedString to use a specific language

155,478

Solution 1

NSLocalizedString() (and variants thereof) access the "AppleLanguages" key in NSUserDefaults to determine what the user's settings for preferred languages are. This returns an array of language codes, with the first one being the one set by the user for their phone, and the subsequent ones used as fallbacks if a resource is not available in the preferred language. (on the desktop, the user can specify multiple languages with a custom ordering in System Preferences)

You can override the global setting for your own application if you wish by using the setObject:forKey: method to set your own language list. This will take precedence over the globally set value and be returned to any code in your application that is performing localization. The code for this would look something like:

[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"de", @"en", @"fr", nil] forKey:@"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize]; //to make the change immediate

This would make German the preferred language for your application, with English and French as fallbacks. You would want to call this sometime early in your application's startup. You can read more about language/locale preferences here: Internationalization Programming Topics: Getting the Current Language and Locale

Solution 2

I had the same problem recently and I didn't want to start and patch my entire NSLocalizedString nor force the app to restart for the new language to work. I wanted everything to work as-is.

My solution was to dynamically change the main bundle's class and load the appropriate bundle there:

Header file

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

Implementation

#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

So basically, when your app starts and before you load your first controller, simply call:

[NSBundle setLanguage:@"en"];

When your user changes his preferred language in your setting screen, simply call it again:

[NSBundle setLanguage:@"fr"];

To reset back to system defaults, simply pass nil:

[NSBundle setLanguage:nil];

Enjoy...

For those who need a Swift version:

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)
    }
}

Solution 3

I usually do this in this way, but you MUST have all localization files in your project.

@implementation Language

static NSBundle *bundle = nil;

+(void)initialize 
{
    NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
    NSArray* languages = [defs objectForKey:@"AppleLanguages"];
    NSString *current = [[languages objectAtIndex:0] retain];
    [self setLanguage:current];
}

/*
  example calls:
    [Language setLanguage:@"it"];
    [Language setLanguage:@"de"];
*/
+(void)setLanguage:(NSString *)l
{
    NSLog(@"preferredLang: %@", l);
    NSString *path = [[ NSBundle mainBundle ] pathForResource:l ofType:@"lproj" ];
    bundle = [[NSBundle bundleWithPath:path] retain];
}

+(NSString *)get:(NSString *)key alter:(NSString *)alternate 
{
    return [bundle localizedStringForKey:key value:alternate table:nil];
}

@end

Solution 4

Do not use on iOS 9. This returns nil for all strings passed through it.

I have found another solution that allows you to update the language strings, w/o restarting the app and compatible with genstrings:

Put this macro in the Prefix.pch:

#define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:@"lproj"]]

and where ever you need a localized string use:

NSLocalizedStringFromTableInBundle(@"GalleryTitleKey", nil, currentLanguageBundle, @"")

To set the language use:

[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"de"] forKey:@"AppleLanguages"];

Works even with consecutive language hopping like:

NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"fr"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"it"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"de"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));

Solution 5

As said earlier, just do:

[[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:@"el", nil] forKey:@"AppleLanguages"];

But to avoid having to restart the app, put the line in the main method of main.m, just before UIApplicationMain(...).

Share:
155,478

Related videos on Youtube

CodeFlakes
Author by

CodeFlakes

Updated on February 23, 2022

Comments

  • CodeFlakes
    CodeFlakes about 2 years

    On iPhone NSLocalizedString returns the string in the language of the iPhone. Is it possible to force NSLocalizedString to use a specific language to have the app in a different language than the device ?

  • quano
    quano about 14 years
    This does not work for me, it will use the default language no matter what.
  • quano
    quano about 14 years
    Nice, works excellently. I changed the initialize method to just do bundle = [NSBundle mainBundle]; instead. That way, you don't need to have all localization files in your project.
  • Panagiotis Korros
    Panagiotis Korros about 14 years
    This didn't work for me, so I used, [[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:@"el", nil] forKey:@"AppleLanguages"];
  • William Denniss
    William Denniss about 14 years
    Didn't work for me either, but [[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:@"el", nil] forKey:@"AppleLanguages"]; did. (NB. you have to restart the App for it to take affect)- Thanks Panagiotis Korros! [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"AppleLanguages"]; to undo, and go back to the default language
  • Ben Zotto
    Ben Zotto almost 14 years
    +1. This is a really nice trick that I haven't seen anywhere else. By creating a "sub bundle" from one of the localization folders, you can get the string stuff to work fine as long as you wrap NSLocalizedString with something that detours here.
  • geon
    geon over 13 years
    Denniss; It seems to work better if you set the language preference before the app is launched. I do it in the main() function, before UIApplicationMain() is called. Once it is actually running, it won't change the used language, but just set the preference for the next time.
  • William Denniss
    William Denniss over 13 years
    in my implementation it's a user-settable thing – so I just pop up a dialog telling them they'll need to restart :)
  • Lukasz
    Lukasz over 13 years
    It Works, almost for all - except for the localized Default.png image.
  • fedmest
    fedmest about 13 years
    You have to set the language before you initialize UIKit and you must specify a complete language+region locale - check this out for a complete example blog.federicomestrone.com/2010/09/15/…
  • Jagie
    Jagie almost 13 years
    I also like his method and I add a method to load png images: +(UIImage )imageNamed:(NSString *)imageFileName{ NSString fullPath = [bundle pathForResource:imageFileName ofType:@"png"]; UIImage* imageObj = [[UIImage alloc] initWithContentsOfFile:fullPath]; return [imageObj autorelease]; }
  • ySgPjx
    ySgPjx almost 13 years
    Very helpful answer! P.S. May sound obvious to non-beginners, but you should insert that line after NSAutoreleasePool * pool .. or a few autoreleased objects will leak.
  • nonamelive
    nonamelive over 12 years
    I guess the best approach is to use [NSLocale preferredLanguages].
  • arnaud del.
    arnaud del. over 12 years
    Excellent Mauro. I noticed that it can also work for files out of your project. If for some reason (as in my case), you need to download strings files from network, and store them in your 'Documents' directory (with the folder structure Documents/en.lproj/Localizable.strings, Documents/fr.lproj/Localizable.strings, ...). You can even though make a NSBundle. Just use this code for path : NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"/Documents/%@.lproj", l, nil]];
  • PKCLsoft
    PKCLsoft about 12 years
    Seems to me that this is the best approach, along with the contribution from Alessandro below. It's not so intrusive and shouldn't require a restart.
  • AmineG
    AmineG about 12 years
    works for NSLocalizedString, but for images it does not work for me
  • satish
    satish over 11 years
    The keyboard is not localized, i'm still getting english version. Could anybody help with this.
  • SirRupertIII
    SirRupertIII over 11 years
    What am I doing wrong? I made a Language class, inheriting NSObject, put this in the implementation, put the method names in .h, then put [Language setLanguage:@"es"]; in my Change Language Button, code runs(button method gets called, and goes to Language class), but does nothing. I have my localizable.strings (Spanish) set up too. But it seems to be working for a lot of other people. Please someone dumb it down for me.
  • arlomedia
    arlomedia over 11 years
    If you're letting users set a language and then telling them to restart the app, just remember that the NSUserDefaults might not be saved if they restart too quickly. Most users aren't this fast, but when you're testing the app you might be too fast and see inconsistent behavior as a result. It took me a couple hours to realize why my language switch was sometimes working and sometimes not!
  • Ben Baron
    Ben Baron over 11 years
    That's not an issue, just use [[NSUserDefaults standardUserDefaults] synchronize]; after calling setObject:forKey:
  • pengwang
    pengwang about 11 years
    /Users/pwang/Desktop/Myshinesvn/Myshine/viewController/Orien‌​tationReadyPagesView‌​.m:193:31: Use of undeclared identifier 'bundle'
  • Jason TEPOORTEN
    Jason TEPOORTEN about 11 years
    @geon and @"Brian Webster", thanks very much. I've got what I needed to assist testing my app for different language settings without having to go through the Internationalisation Settings.
  • Kof
    Kof almost 11 years
    IMPORTANT: This won't work if you call [[NSBundle mainBundle] URLForResource:withExtension:] before.
  • JohnPayne
    JohnPayne over 10 years
    setting AppleLanguages will change a language at runtime if done in main() - true! but... the FIRST TIME the app is installed, the nsuserdefaults are initialized AFTER UIApplicationMain() is called, which will ignore the previously set AppleLanguages and will require an ugly force-restart of the app to see the desired language.
  • Mikrasya
    Mikrasya over 10 years
    @KKendall you call it like this: [Language setLanguage:@"es"]; NSString *stringToUse = [Language get:@"Your Text" alter:nil];
  • haxpor
    haxpor over 10 years
    It works on iOS7 as well, I have to switch from Brian's solution to this as it seems like iOS overrides the languages option again thus I stuck with the first-time setting of language. Your solution works like a charm!
  • gklka
    gklka over 10 years
    @powerj1984: no, it will change only the strings in your source files. If you want to change the xib languages, you have to reload the xibs by hand, from the bundle of your selected language.
  • Idan Moshe
    Idan Moshe about 10 years
    How do I get rid of the warning 'ovverride...'?
  • Dk Kumar
    Dk Kumar about 10 years
    @gklka I have follow the steps given by Tudozier but my XIB's are not changing the language , as you told reload XIB by hand , what tis actually mean to reload XIBs ?
  • gklka
    gklka about 10 years
    @DkKumar: You have to do something similar to this: stackoverflow.com/questions/21304988/…
  • Dk Kumar
    Dk Kumar about 10 years
    @gklka Your answer seems to correct and i have did the same steps as you descried in your answer , but what is problem is if we change the bundle path than it will find all the resource (i.e. .png file used in XIB)in the same bundle , so we have to over copy the images folder in all the bundle like en.lproj, es.lproj and so on .. so will effect on increasing IPA size , so is there any way to overcome on this problem ? as you said in your post, let me try on this and let you more on this Thanks for helping me out for the same
  • Dk Kumar
    Dk Kumar about 10 years
    @gklka I have checked it is working but there are 2 major problems #1 you have to initialize XIB every time #2 my IPA size in increased from 16.5-->195 MB this is large change i think because there are lots of images are there in my application
  • gklka
    gklka about 10 years
    @DkKumar: yes, these side effects are known with this method. There is one more: you have to modify all of your Storyboards one by one if something changes. Please let me know, if you find anything better!
  • Wirsing
    Wirsing about 10 years
    Any experience with this? Does it work? Gilad, are you still using this successfully?
  • Gilad Novik
    Gilad Novik about 10 years
    Hi @Wirsing , this works great for me so far. I've even uploaded one app to the store and no complains by Apple.
  • beryllium
    beryllium about 10 years
    Add #undef NSLocalizedString just before #define to disable the warning
  • James Tang
    James Tang about 10 years
    This is a great solution, I've also referencing this here: medium.com/ios-apprentice/905e4052b9de
  • Gilad Novik
    Gilad Novik about 10 years
    Hi @JamesTang , Thanks for the reference and your post - I found a lot of useful information there regarding localization.
  • Jawad Al Shaikh
    Jawad Al Shaikh almost 10 years
    @Gilad your method works perfect for dynamic strings (strings that i defined in localizable.strings) but as for storyboard buttons and labels it only work at main method only. so can you extend your answer to include UI controls localization? i mean how to refresh (without closing) storyboard after i invoke [NSBundle setLanguage:@"??"];?
  • Gilad Novik
    Gilad Novik almost 10 years
    As for XIB/storyboard: you need to make sure you call this method BEFORE you load the view. As far updating views live: in my case I simply reloaded the view controller (I put it in a navigation controller and just replaced the controller. Upon reloading it - it got the new translated strings). I'm working on a cocoapod for it, I'll probably include an example there as well. Stay tuned...
  • mohammad alabid
    mohammad alabid almost 10 years
    @Gilad its working perfectly on Strings but the problem come when using localized xib view!!
  • Jawad Al Shaikh
    Jawad Al Shaikh almost 10 years
    based on @JamesTang posted link: storyboard refresh through controller can be done with: including appDelegate.h then: appDelegate *delg = [UIApplication sharedApplication].delegate; delg.window.rootViewController=[self.storyboard instantiateInitialViewController]; above two lines will reset storyboard to idle case, so make sure no activities going on while doing that, also you need to store the current lang somewhere instead of having 'en' as default everytime app is booted...
  • mohammad alabid
    mohammad alabid almost 10 years
    This worked for me, just load the XIB manually, it may be not perfect solution but it will help stackoverflow.com/questions/8712049/… @Gilad Thanks for your help
  • Gilad Novik
    Gilad Novik almost 10 years
    @mohammadalabid there is really no need to load the language manually - I've successfully used this code with XIB's as well. My trick was to have the root controller as a UINavigationController and right after I change the language - I use its 'viewControllers' property to reload the XIB. rootNavigationController.viewControllers=@[[storyboard instantiateViewControllerWithIdentifier:@"main"]]; I'll post an example to github soon.
  • JERC
    JERC almost 10 years
    Thanks @chings228 it is usefull for me, but this not change the default launch image (splash) for the app I have diferents splashs for each language. do you know how to apply for this??
  • chings228
    chings228 almost 10 years
    i think the splash runs before the main program start to run , so i don't know how to override it , may be plist can help but it may work for next time the app opens
  • neowinston
    neowinston almost 10 years
    Hi Gilad, have you posted the example on github already? Thanks!
  • Khant Thu Linn
    Khant Thu Linn over 9 years
    Hi this is great. It work for me. But it doesn't work for image. I have asked here. Can anyone help me please? stackoverflow.com/questions/25379056/…
  • abbood
    abbood over 9 years
    related question basically how to do the same with localized storyboards
  • GRW
    GRW over 9 years
    Simple solution does everything I need. Was able to use this as a guide to solve my problem. If pathForResource returns nil because I don't have a localization file then I use pathForResource:@"Base" since nothing else I have tried pulls strings from the base localization. Thank you.
  • Sunkas
    Sunkas over 9 years
    Also make sure to remove the "AppleLanguages" key just AFTER UIApplicationMain() is called, i.e. in applicationDidEnterBackground in AppDelegate. This so the user can change language manually later!
  • Shah Nilay
    Shah Nilay over 9 years
    I am doing same above code also reintialized UIviews but app's language not reflected instantly. If pressed HOME & again starting app then also not changing language. If app run another time from xcode then it is working. What is missing?
  • hasan
    hasan over 9 years
    Looks like non of these solutions will flip the layout of the views for the rtl languages without a restart. right?
  • Kong Hantrakool
    Kong Hantrakool about 9 years
    Does this work on localization for xib file ? I have .xib file and .strings to translate UIs name in particular language. I tried and it does not work with XIB but I am not sure if I have done things correctly
  • Muhammad Saad Ansari
    Muhammad Saad Ansari about 9 years
    Hi Gilad, thanks for the great solution but in my case its changing the text but not alignment from LTR to RTL on arabic selection. Working with proper AutoLayout and RTL alignment is working when user changes language of his device from device setting.
  • Oblivious Sage
    Oblivious Sage about 9 years
    We ask that you not just link to a solution in your answer; the link might stop working some day. While you don't have to remove the link from your answer, we do ask that you edit your answer to include a summary of the relevant section of the linked article.
  • qman64
    qman64 over 8 years
    Kong sorry for the delayed response. This works where ever you use NSLocalizedString. So it will not work directly in an XIB. You would need IBOutlets to the strings in the XIB and then would have to programmatically set the string values in code.
  • Alex Zavatone
    Alex Zavatone over 8 years
    This is horribly broken in iOS 9, returning the null for all strings.
  • Tudor
    Tudor over 8 years
    Indeed. iOS 9 doen't support this anymore.
  • Dan Rosenstark
    Dan Rosenstark over 8 years
    How did you know how to do this??! Amazing. Anyway, translated to Swift here: stackoverflow.com/a/33685575/8047
  • turingtested
    turingtested over 8 years
    What about if using Swift, then there is no main.m?
  • Van Du Tran
    Van Du Tran over 8 years
    but there is no main.h in swift?
  • Ravi Ojha
    Ravi Ojha over 8 years
    Its working , but it not set those text which is set from didfinishlaunching ??
  • Mihai Fratu
    Mihai Fratu over 8 years
    This doesn't work with plural items defined in Localizable.stringsdict. Any idea if there's a possible fix?
  • Mihai Fratu
    Mihai Fratu over 8 years
    This doesn't work with plural items defined in Localizable.stringsdict. Any idea if there's a possible fix?
  • Mihai Fratu
    Mihai Fratu over 8 years
    This doesn't work with plural items defined in Localizable.stringsdict. Any idea if there's a possible fix?
  • eonil
    eonil about 8 years
    This code from the project helped me a lot. How to find a bundle for specific language code --- NSString *path = [[NSBundle mainBundle] pathForResource:lang ofType:@"lproj" ];
  • royherma
    royherma almost 8 years
    Any idea of how to do this for swift? @gilad
  • royherma
    royherma almost 8 years
    If anyone is looking for a swift result, here is how to force locale without needing a re-launch: stackoverflow.com/a/38429383/1511877
  • miham
    miham almost 8 years
    I see you are also facing problems with Slovenian language :) To improve this answer for languages not supported by iOS, have you figured out if we can set custom localizable strings which will be used for system controls in app (Edit, Done, More,...)?
  • dvp.petrov
    dvp.petrov almost 8 years
    This is not working for localised UIImages. Is there any way to use localised images using NSBundle and that are reloaded dynamically without the need of killing your app?
  • Anilkumar iOS - ReactNative
    Anilkumar iOS - ReactNative almost 8 years
    This class is working fine, but after changing language to another, its not effecting.
  • Harsha
    Harsha almost 8 years
    This works. For beginners in swift, just create a bridging header for this and use. Works perfectly.
  • Bhavin Bhadani
    Bhavin Bhadani over 7 years
    @Gilad when I change it to other language at runtime in my app and go back to view controller .. nothing effects ...so any idea why is it so???
  • Gilad Novik
    Gilad Novik over 7 years
    @EICaptainv2.0 : you need to reload the controller (check one of my previous comments explaining this issue). When you reload the controller - it will reload the view (from the new bundle)
  • Chuck Krutsinger
    Chuck Krutsinger over 7 years
    @Gilad been banging my head against the wall all day. Yours seems like the way to go, but I am not getting my storyboard to load the localized storyboard. No matter what, it stays in the default language. I put a break in setLanguage does get called once in AppDelegate and once to change language before I load my storyboard. I also put a break in localizedStringForKey but it never gets called. Will this only work if my code manually calls localizeStringForKey? I was hoping this would work for the storyboard loading process itself.
  • Gilad Novik
    Gilad Novik over 7 years
    @ChuckKrutsinger you need to reload the storyboard (default template loads it once and save it to the app delegate) - you need to reload it after you change the language so it will use the new storyboard (with the right language).
  • Chuck Krutsinger
    Chuck Krutsinger over 7 years
    @Gilad - Thanks for getting back. I was already changing the language prior to loading the Storyboard. Problem is that UIStoryboard does not call localizedStringForKey when loading those localized storyboards. It appears to call + storyboardWithName:bundle: passing in a bundle that contains the localized storyboard. I am going to use that mechanism to handle my situation as well.
  • Chuck Krutsinger
    Chuck Krutsinger over 7 years
    @Gilad - Figured out a simple way to accomplish what I needed based on extending your solution with one additional function: [UIStoryboard storyboardWithName:storyboardName bundle:[NSBundle localizedBundle]] using +(NSBundle )localizedBundle { NSBundle bundle=objc_getAssociatedObject([self mainBundle], &_bundle); return bundle ? bundle : [self mainBundle]; } The localized bundle has localized interface builder storyboards in it.
  • Majid Bashir
    Majid Bashir over 7 years
    @ChuckKrutsinger can you please explain how to use your code..?
  • Chuck Krutsinger
    Chuck Krutsinger over 7 years
    @magid I first localized the storyboards using Interface Builder, but NOT Base localization.
  • Chuck Krutsinger
    Chuck Krutsinger over 7 years
    @magid I first localized the storyboards using Interface Builder, but NOT Base localization. When I programmatically launch the storyboard, I need to tell UIStoryboard to look in the localized bundle, which is pointed to by Gilad answer above for NSBundle+Language. The code to retrieve the localized storyboard is: UIStoryboard* aStoryboard = [UIStoryboard storyboardWithName:tStoryboardName bundle[NSBundle localizedBundle]] Hope that helps.
  • iDevAmit
    iDevAmit over 7 years
    @turingtested have you tried on swift and storyboard, is it working?
  • Mohammed Hussain
    Mohammed Hussain over 7 years
    How to use it i dont understant or it not working in simulator
  • Biranchi
    Biranchi over 7 years
    I have Localizable.string file , but still its not working on iOS 10.2
  • Mahesh Narla
    Mahesh Narla about 7 years
    Hi , How to localize dynamic text which is coming from server, in my application every text i have to display in simplified chinese language, But how to display the text in chinese which is coming in english. help me.
  • Mahesh Narla
    Mahesh Narla about 7 years
    Hi , How to localize dynamic text which is coming from server, in my application every text i have to display in simplified chinese language, But how to display the text in chinese which is coming in english. help me.
  • user3752049
    user3752049 almost 7 years
    I added this before UIApplicationMain(argc but still the language change only takes effect after restart. Any way to avoid this ?
  • Ash
    Ash almost 7 years
    It works only for 1st time after that it again loads into device pref. language ..
  • Mecki
    Mecki almost 7 years
    @Aks Works every time for me. Make sure you are starting the correct scheme, make sure you starting from within Xcode (relaunches, forks, etc. won't get the argument) and make sure that you don't override the language in Options as with newer Xcode versions Apple offers that as well.
  • Ash
    Ash almost 7 years
    Thanks for your reply @Mecki.. For me its not working in xcode but when I mention in code, it work.. But still if I have set my device with some other preferred languages it needs to restart the app to load into my preferred language which I am passing in arguments....
  • Mecki
    Mecki almost 7 years
    @Aks When using that on a device, it will only work when started directly from Xcode, it won't work when you start the app again by tapping its icon on some device and it will also not work when the app is killed (e.g. because it went to background) and gets restarted by the system (as this restart is not a restart done by Xcode) - so switching to a different app and back may not work if iOS has to kill your app in-between (e.g. because it needs the memory).
  • Ash
    Ash almost 7 years
    I could not get this working.. Though I am settings setLanguage call in my main.m file..
  • Hogdotmac
    Hogdotmac over 6 years
    this hangs the simulator
  • user3752049
    user3752049 over 6 years
    couldn't get this to work on iOS 11. Anyone else facing the same issue ?
  • Gallymon
    Gallymon almost 6 years
    This approach worked for me and I was able to changes languages on-the-fly. Note that language codes like "es", fr" and "en" worked fine. But "zh" (for Simplified Chinese) failed and gave me null strings back. I did a global search on my system for "es.lproj" to see where the files I was accessing were and I discovered there that "zh.lproj" is actually "zh-Hans.lproj".
  • Bartłomiej Semańczyk
    Bartłomiej Semańczyk about 5 years
    This is a brilliant answer;)
  • Krunal Nagvadia
    Krunal Nagvadia about 5 years
    Thanks. Working Well.
  • Dilip Tiwari
    Dilip Tiwari over 4 years
    great answer.helped me
  • Max
    Max over 4 years
    This is hacky (so are all the other answers), and it was easiest to implement in the unit test I was writing.
  • Botond Magyarosi
    Botond Magyarosi about 4 years
    Avoid the key AppleLanguages. The key is used internally for Xcode for debugging purposes and might break with new SDK releases. Starting from iOS 13 use preferred languages: reddit.com/r/iOSBeta/comments/bxfkzm/… If you're supporting pre iOS 13 versions prefer a custom solution where the behavior is testable and does not rely on private implementations.
  • L33MUR
    L33MUR almost 4 years
    You can combine this Argument pass with the change in StandardUserDefaults and it will work like a charm every time
  • Rémi B.
    Rémi B. over 3 years
    This answer is great because it also works in a Swift Package running on Linux for example.
  • Hasan Can Gunes
    Hasan Can Gunes about 3 years
    Yes it is working but app needs to restart to change language.