22

Lets say my app only runs in English. But I do not want to release a new version for every time I add a new language. My proposal is to load this localizable.strings file remotely into my app.

My app has facility to load files from ftp sites.

Do you guys think is possible to load languages this way? Or does the App has to compile the language file at compile time?

Forge
  • 6,538
  • 6
  • 44
  • 64
mskw
  • 10,063
  • 9
  • 42
  • 64
  • Same question as http://stackoverflow.com/questions/12358379/is-it-possible-to-access-the-app-bundles-en-lproj? – Martin R Sep 10 '12 at 19:57
  • The question seems to be allready answered [here](http://stackoverflow.com/a/6075533/1651167) – Shelm Sep 10 '12 at 19:58
  • 1
    Is simular but people answer different questions depending on how they are asked. This one obviously has the better answer below. – mskw Sep 10 '12 at 20:10

1 Answers1

36

All localized string resources (plus many other kind of resources) are extracted from the bundle. Usually an app uses the "main bundle" which is the one that is created by XCode together with your app. But you can create separately any other bundle, provided you make it with the correct structure, then you can download it in your app and finally extract a localized string using the NSLocalizedStringFromTableInBundle() function.

So let's say you extract for a key "KEY" the language translation, then the normal syntax would be:

NSString *translated = NSLocalizedStringFromTable(@"key",nil,nil);

but there is a variant of this option that allows you to specify the bundle:

NSString *translated = NSLocalizedStringFromTableInBundle(@"key",nil,myBundle,nil);

In the standard case you replace myBundle with [NSBundle mainBundle] but if you want to use another bundle you can specify it in this way:

NSString *myBundlePath = "the path to the downloaded bundle";
NSBundle *myBundle = [NSBundle bundleWithPath:myBundlePath];
NSString *translated = NSLocalizedStringFromTableInBundle(@"key",nil,myBundle,nil);

The full structure of a bundle can be seen in the "Bundle Programming Guide" in the Apple docs, but in your case you can simply create in this way:

  • in your Mac create a directory, and call it "MyBundle"
  • inside this directory move your localized string(s) (if you have multiple languages in the bundle then the localizable.strings file will be inside the lproj directories: en.lproj, it.lproj, fr.lproj, ...)
  • then rename the directory to "MyBundle.bundle"

You will notice with the last operation that now this object is seen as a standalone object but in fact it is a directory.

Now you can decide to have a multiple-bundle approach or follow a single-bundle technique: in the latter case you can package all the languages and then use the unique updated bundle for language translation by using the automatic system localization rules; in the other case you can make a bundle for each language and then - based on the currently selected language - load the appropriate bundle and choose it for your translations.

Titouan de Bailleul
  • 12,920
  • 11
  • 66
  • 121
viggio24
  • 12,316
  • 5
  • 41
  • 34
  • 3
    Very useful! Unfortunately, if you want to add localizations of App Store metadata (which you probably want if you add a new localization), you have to submit an app update anyway... – Scott Berrevoets Sep 10 '12 at 20:08
  • 2
    Yes, metadata localization implies app resubmission. In such case you would merge your new languages in the bundle. But the simplicity of the downloaded bundle approach is such that you can provide localization (and translation error fixes) a lot before any app update. Sure on the next app update (bug fixes, new features) you will merge new languages in the main bundle and you will update the metadata too. – viggio24 Sep 11 '12 at 05:44
  • Just one note, the file should be Localizable.strings at the end. Careful with capitalization, because its case-sensitive. – Slavcho Mar 01 '22 at 13:49
  • Basically even main bundle is a folder; hence would altering `localizable.strings` files of that folder update `NSLocalizedString(...)` result, or, is changing to `NSLocalizedStringFromTable(...)` always required??? – Top-Master Aug 11 '23 at 06:42