12

I have a project with 3 targets. Each target needs to suppport only one language, but the language is not the same for each target. Currently I have

  • Target 1 (es)
  • Target 2 (es)
  • Target 3 (pt)

Most of my strings are in a Localizable.strings file, and I simply target a different file for each target. However, a number of strings are in my storyboards. My problem is that it does not seem possible to create different storyboard localization files for each target. If I change the targeting of the portuguese file, the targeting of the spanish file changes automatically.

A possible solution is to duplicate each Storyboard for each target, but this won't scale well as the number of tagets grow. I could also modify all the text with NSLocalizedString in each ViewController, but this seems tedious and error prone.

Is there a better solution?

1
  • 1
    might want to put an xCode tag on this question as the answer is very likely some sort of xCode setting
    – NSGangster
    Commented Nov 16, 2015 at 22:44

3 Answers 3

9

Shared Storyboard across targets

While this answer is the preferred approach, you can assign different Storyboard localizations to different targets, while sharing the same Storyboard across all targets.

Prerequisites:

Follow this instructions in this answer.

Concept:

You want to have the Main.storyboard in each target, but a different Main.strings in each target. Additionally, you do not want all localizations to be available in each target.

To achieve this, you must manipulate the .lproj directly, a process which is hidden when merely using the File Inspector.

Step by step:

  1. Create all the pieces by following the steps in this answer.
  2. From any target, remove the Main.storyboard. Of course, select Remove Reference to keep the storyboard around.
  3. In the Finder, locate Base.lproj. Drag and drop Main.storyboard back to your project, and select every target.
  4. In the File Inspector, ensure that the languages are not selected, and that you are still using Localizable Strings. enter image description here
  5. In the Finder again, locate en.lproj, es.lproj, fr.lproj, etc. Notice that they each contain a version of Main.strings. Drag these .lproj (the entire directories) back into your project. This time, do not select any target
  6. One last time, in File inspector, associate each Main.strings to the desired target. Repeat for each .strings. enter image description here

Conclusion

By decoupling the .lproj from the .storyboard in the Project Navigator, you can associate files and targets freely.

Demo:

See it at work using a French target, on a device with language set to Français in the Settings:

French example on iPhone 4


► Find this solution on GitHub and additional details on Swift Recipes.

5
  • I did this, and it did not work. While tha .strings files are added to the correct targets, they are not being read by the storyboard. The contents of the .strings are never used; I just see whatever text is in the original storyboard. Commented Nov 20, 2015 at 17:06
  • This may happen if you are targeting for a language not available on the device. Make sure you go to Settings on the device, and pick the language you are targeting for. I have added a screen shot & an actual Xcode project for you to verify that my post is accurate, and that the technique I outline has been verified and tested. Commented Nov 21, 2015 at 9:05
  • But then the target is not supplying only one language. This answer is a bit better than the other one in that each target supports the base language plus the target language instead of all languages, but it still does not solve the original problem. Commented Nov 21, 2015 at 13:45
  • each target supports the base language plus the target language instead of all languages: isn't it exactly what you are trying to do? You must use a Base if you do not want to duplicate the storyboards. By definition, "localized" mean "run in the preferred language". If you want your app to run in, say, Esperanto, regardless of the OS, then you cannot use any of the localization support ; you must create your App in Esperanto. This is when the post compilation scripts and the plist manipulation scripts come into play. Commented Nov 22, 2015 at 7:29
  • 1
    No, I am sorry if the question reads that way. Each target must be available in exactly one language. Commented Nov 22, 2015 at 12:05
7
+25

Shared localizations across targets

  1. Assuming you already have multiple languages in your project, in the Project Navigator, select your storyboard (say Main.storyboard)

  2. In the File Inspector, under Localization, add English. Pick Localizable Strings which is the default. This will create a Main.string for each language, and share your Storyboard across all languages.

    Create a Main.strings

  3. Merely clicking that checkbox in step 2. will add a Main.string (English) for that language, specifically for that Main.Storyboard. Pay special attention to the new hierarchy, these are not Localizable.strings but Main.strings, derived from Main.storyboard:

    New localizations per Storyboard

  4. Localize in each language file to your heart content.

For example, starting with a UILabel which message was in Esperanto, it will appear in English when the device runs in English:

/* Class = "UILabel"; text = "Tiu mesaĝo estas en Esperanto"; ObjectID = "acC-pA-eMt"; */
"acC-pA-eMt.text" = "This message is in English";

Start here to add multiple languages to your project:

In the event you need to add more languages, follow these steps:

  1. In the Project Navigator, select your Project

  2. In the Project and Target List, select, once again, the Project

    Pick the project

  3. Select the Info tab

  4. Under Localizations, keep Use Base Internationalization (unless your UI itself must change across languages)

  5. Click +, pick a new language. In the dialog presented to you, select every Storyboard you want to have multiple localizations for.

    Pick Storyboards to be localized

If you missed Storyboards at Step 5. you can simply add a new language to that a storyboard by following the steps in Assuming you already have multiple languages.

6
  • This makes each target support all languages. But as I said, each target needs to only support one language. Commented Nov 17, 2015 at 13:20
  • Once the Main.strings exist, you can pick the ones you need on a per-target basis. Multiple targets create multiple executables (one per language in your example), which is very different from a single, multiple language app. In essence, you are not localizing your app, you are creating multiple apps. Commented Nov 17, 2015 at 23:06
  • No. At least in XCode 7, if I add the portuguese Main.strings to Target 3 , all other Main.strings are added automatically to the same target. Even if that would somehow work, since to get ot that point I had to add localiazions to my project, all my tarets will be amrked as having localization, when they don't. And this will be a problem when I publish my app. Commented Nov 18, 2015 at 14:58
  • Good point. I have created stackoverflow.com/a/33791181/218152 to address the .lproj concerns and clearly address the target associations. Commented Nov 18, 2015 at 21:57
  • any idea how can have a different Main.strings for each target? in other words having one storyboard but have different Main.Strings file for each language. @SwiftArchitect
    – hasan
    Commented Feb 23, 2017 at 12:30
0

All you need: to make common xcode workspace for your app, then to create a duplicates of main xcodeproj file for your set of languages and make different targets for all of them, also then you can set language for individual project settings in new xcodeproj's. Also you easy can tune build phase 'Copy Bundle Resourses' and others. I use this method. If you have a Xcode's crash during adding project in workspace - open project with Xcode, rename it and rename or duplicate targets (I think same names cause this issue).

Not the answer you're looking for? Browse other questions tagged or ask your own question.