views:

73

answers:

2

Using the Settings app in the iPhone simulator to switch languages is a PITA way of testing localization tweaks. I'm trying to figure out a way to switch localizations (en/fr/es/etc) on the fly in my app with a debug setting without restarting the app.

NSBundle provides ways of requesting localized resources from an arbitrary localization, e.g.

- (NSString *)pathForResource:(NSString *)name ofType:(NSString *)extension inDirectory:(NSString *)subpath forLocalization:(NSString *)localizationName

But I find no equivalent for the string management subsystem. It sounds from these questions that you can override the registered defaults, which sounds goofy and requires an app restart.

Are there any other strategies here? If I wrapped NSLocalizedString with something that in debug builds did its own work, what's the shortest path to loading a given .strings file? Is there a programmatic way to access those strings tables without going and parsing them raw myself?

Thanks.

A: 

Set the AppleLanguages default to an array consisting of the preferred languages, most preferential first. For example if you only care about English, set it to '("en");'

Graham Lee
Hey Graham, thanks for the quick reply. I really hate to be That Guy, but I did note that I was looking for an on-the-fly solution that doesn't require an app restart, and linked to your answer to previous related questions. Looks like I'll need to parse the strings plist directly.
quixoto
@quixoto are you saying that if you programmatically update the `AppleLanguages` default, it _doesn't_ affect which strings table is used?
Graham Lee
It did, but seemed to do so only after restarting the app. Presumably the locale subsystem initializes/caches the string table at app start time?
quixoto
Unfortunately, this trick only works after restarting the app. (Tested on iPad with iOS 3.2)
0xced
+1  A: 

The only way to do this that I've figured out is by using the subtle trick suggested by this answer. You can wrap NSLocalizedString() in a function that knows about a localization "override", and chooses how to get its strings based on whether that is set. When you want to override, you can create a "sub bundle" from the localization's directory, and then pull string from that bundle. Here's the gist of it:

if (CurrentLocalization != nil) {
    NSBundle * locBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:CurrentLocalization ofType:@"lproj"]];
    return [locBundle localizedStringForKey:key value:nil table:nil];
} else {
    return NSLocalizedString(key, @"");
}    

etc.

quixoto