3

I have an app where all the user facing strings use NSLocalizableString(). I've never localized an app so I watched WWDC 2018 video New Localization Workflows in Xcode 10. From there I created a new project, a Single View App. Base localization is on by default. On the storyboard I added one UILabel and constrained it in the center of the view. I added an outlet to it in the view controller:

@IBOutlet weak var label: UILabel!

And I set its text in viewDidLoad:

label.text = NSLocalizedString("Hello World", comment: "")

Build and run and it works fine.

Now I add a localization. I select the project and add Spanish.

enter image description here

Then I Export For Localization... on the Editor menu. I open the file through this path:

es.xcloc -> LocalizedContents -> es.xliff

In there I find the "Hello World" key and I change the value to "Hola Mundo" and save the file.

...
<file original="MyProject/en.lproj/Localizable.strings" datatype="plaintext" source-language="en" target-language="es">
    <header>
      <tool tool-id="com.apple.dt.xcode" tool-name="Xcode" tool-version="10.1" build-num="10B61"/>
    </header>
    <body>
      <trans-unit id="Hello World">
        <source>Hola Mundo</source>
        <note>No comment provided by engineer.</note>
      </trans-unit>
    </body>
  </file>
...

Then back to Xcode and Import Localizations. Here's the first problem:

enter image description here

Why is this a Mismatched Translation?

I go ahead and import anyway. I edit the scheme as follows:

enter image description here

When I run I get "HELLO WORLD". It's uppercase because that's the localization debugging indicating there's no translation.

What am I missing?

Murray Sagal
  • 8,454
  • 4
  • 47
  • 48

1 Answers1

3

We have a few problems here. First, when you do NSLocalizedString("Hello World", comment: "") what is actually happening is that you try to fetch a localized string with key Hello World and since Xcode can't find that key, it returns the key itself, which you set for the label. So, for best practices, consider using a key that doesn't contain a white space on it. Maybe something like hello-world-label. Then, it would be:

NSLocalizedString("hello-world-label", comment: "")

This will generate the following after you export for localization:

<trans-unit id="hello-world-label">
    <source>hello-world-label</source>
    <note>No comment provided by engineer.</note>
</trans-unit>

And now you have to add <target> tag to specify the actual translation. Therefore:

<trans-unit id="hello-world-label">
    <source>hello-world-label</source>
    <target>Hola Mundo</target>
    <note>No comment provided by engineer.</note>
</trans-unit>

Then just import back the localizations and you should be fine.

EDIT

After doing that, a Localizable.strings file should have been generated. Click on it and take a look into the File Inspector on the right side of Xcode under the Localization section. You will that the file is only localized for Spanish. So go ahead and select English checkbox. Then, your Localizable.strings will be editable for both English and Spanish, as you can see on the figure below:

enter image description here

Now you edit the English version of that file for having both languages in your app.

alanpaivaa
  • 1,959
  • 1
  • 14
  • 23
  • It works for Spanish. There is no error on import and the translation appears. However, now there is no English. – Murray Sagal Feb 06 '19 at 04:33
  • 1
    I went with the version of NSLocalizedString that takes a default value: `label.text = NSLocalizedString("hello-world-label", tableName: nil, bundle: Bundle.main, value: "hello world", comment: "")` and now I don't need to mess with `Localizable.Strings (English)`. – Murray Sagal Feb 06 '19 at 18:35
  • How is it possible that Apple does not realize that the `target` tag is required? – Murray Sagal Feb 06 '19 at 18:39
  • And a large number of my strings are Swift multiline literals. When I change the above example to a multiline literal it doesn't appear in the exported xliff file. – Murray Sagal Feb 06 '19 at 20:46
  • If you switch to unique keys, as suggested in this answer, you definitely have to unique the default value for English. NSLocalizedString("hello-world-label", value: "Hello world", comment: ""). Also make sure you've turned on Base localization. Your keys will be in the Base, and you'll have a separate en.xliff (and en.lproj folder) for the English. Check out this tutorial: https://ibabbleon.com/iphone_app_localization.html – Localizer Jan 30 '21 at 00:10