Text extraction tools for macOS and iOS app localization Jul 10 2019

Localization is not only translating content but adapting the content to culture, language and customs. This makes our apps more intuitive and engaging for our users. We can localize not only text, but we can also localize images, sounds, shortcuts, etcetera. A crucial part of localization is obtaining the text to be localized. In this post, I’ll focus on text extraction for localization. This post is not a general introduction to localization of apps, but when you finish reading the post, you’ll have a better understanding of crucial aspects of localization and can research other specific topics that you are interested in. As always, check my notes at the end of the posts where I add links and notes to explore related topics, let’s begin.

Prepare your app for localization

If we want our app to support multiple languages, we need to prepare our app for localization. You might find the steps easy if you do it regularly, but if you seldom do work on your apps translations, it’ll be easy to forget some small detail. You can bookmark this post and come back to check for any information that will help you.

The good news is that once you finish preparing the texts on your app for localization, they can easily be extracted and you can generate files that you can share with the person that is helping you with the translation.

Let’s have a look at some generalities on how to prepare your app. We’ll start with Storyboards and xib files, the process is simple.

Preparing Storyboards and xibs for localization

If you are using Storyboards or custom xibs (Interface Builder), you have it easy. By default, all apple components support localization. The only task you need to do is to make sure you add the Localizer hint for every component (label, button or text). You can find the Localizer hint in the identity inspector in Xcode (Alt+Command+3).

Where to find localizer hint screenshot

That’s it for Storyboards and xib files, now let’s see how to prepare our code when we declare our views in code.

Preparing our code for localization

If you have created your views in code, go through all your code and make sure all the text that is being presented to the user goes through NSLocalizedString. This is easier explained with an example, imagine we have the following code:

1
2
3
4
5
6
  let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
  button.backgroundColor = .red
  button.setTitle("Profile", for: .normal)
  button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)

  self.view.addSubview(button)

Look at the title, the text is hardcoded so that button title will always be “Profile” no matter the user preferences in language. To prepare the code for localization use NSLocalizedString, let’s see the following example:

1
2
3
4
5
  let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
  button.backgroundColor = .red
  let title = NSLocalizedString("profileButtonTitle", comment: "This is the button the user sees when he wants to see its profile")
  button.setTitle(title, for: .normal)
  button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)

Notice that the key we are using to identify the localized string is profileButtonTitle this will be the key in the translation file not necessarily the text that will appear to the user.

If the key is not defined in the translation file for a specific language, it will show the value in the base.lproj. If it doesn’t exist in the base language dictionary, it will display the key.

Now that we have all our text ready for exportation in our Storyboards, Interface builder files (xibs) and code, we can extract the text and share the files with a translator or someone that will help us with the localization. To generate a file that our translators can work with, we need to extract a list of all the text that needs a translation. I’m going to show you how to use the tools from the command line, it is faster, and you can create scripts to automate the tasks (e.g. you could add your script as a hook in your git workflow to run after you do a commit).

Tools for extracting text to be translated

If you want to extract all the text to be localized, you can use the xcodebuild command to do it.:

1
$ xcodebuild -exportLocalizations -localizationPath ~/Desktop/my_project_localizations -project ~/Work/current_project/project.xcodeproj -exportLanguage es -exportLanguage en

This will get you all the text you want to translate in XLIFF format. You can then give those files to your translator and work on the translation of your app going back and forth, you exporting and importing and the translator working on your XLIFF files.

That is the preferred way to obtain the text for translation. If you wish to get the translation texts of individual xib files or source files, you will use other tools. Let’s first see how to do it for xib files and Storyboards, and then for source files.

Working with xib files and storyboards

To obtain all the text to be translated from a xib file use ibtool, this will generate a file that you can send to your translator. You would use a command similar to the following:

1
$ ibtool YourFComponent.xib --generate-strings-file YourComponent_new.strings

This will generate a strings file that contains the texts you would want to translate, you can generate the files manually and then send them to your translator. The only problem is that you’ll have to merge the changes from the translator to the strings file manually (using a difftool that is).

For storyboards, the process and tool are the same, but we use our storyboard file instead of the xib. For example:

1
$ ibtool Main.storyboard --generate-strings-file YourMainStoryboard_new.strings

And that will generate the file YourMainStoryboard_new.strings file. That’s it for xib files and storyboards, let’s check how to obtain the text from source files.

Working with source files

If we want to only extract the translated text for source files, we can use the genstrings tool to do this.

1
$ genstrings -o directory_to_store_strings_files/  the_file_we_want_to_parse.swift

After running that command, you’ll obtain a Localizable.strings file inside the output directory (directory_to_store_string_files in our example). You can then send the Localizable.strings file to your translator. We have the same problem that we had with xib and ibtool, you’ll be in charge of doing the merge of the translations.

And that is it, those are the main ways to extract the text to be translated from our Apps.

Final thoughts

If we create the habit of using NSLocalizedString and adding Localazer hint in our source-code and interface builder(and storyboards) respectively, we will make the process of localization much more easy for us. We could have exported the localization using Xcode. If you want to go with that is an option, just navigate to your Project info by selecting your project icon from the File Navigator, then click on Editor > Export For Localization… this will generate the files to send to your translator. To import the translations, go to Editor > Import Localizations in the main menu when you are viewing your Project info.

I like using the command line, it gives me more flexibility and the ability to create scripts to automate this type of tasks. As I mentioned before we could create a git hook that runs a script that is in charge of exporting our translations, check if there are any differences (using a diff tool) and if there are any new required translations send an email. That is beyond the scope of this post, but if you think it is useful you can send me a message, and I’ll write a post explaining how to do that.

As always I hope this was useful, if you have any comments, questions or feedback let me know.

Related topics/notes of interest


** There is no comment system yet, but you can send me a message on twitter @rderik or send me an email: derik[at]rderik[dot]com.