iOS, Apple’s mobile operating system, has been thriving at an incredible pace over the last few years. In fact, its growth is so rapid, that according to Apple, there are currently over 150 countries where the App Store is available and more than 40 languages that iOS devices support.
This makes it quite obvious that your iOS app needs to address users from different regions in the world in multiple languages from the very beginning. How to get there is the question that this end-to-end iOS tutorial on internationalization and localization intends to answer.
iOS developers often tend to use both terms interchangeably. In reality, while being interconnected, they are quite different. Therefore, we’ve divided this iOS tutorial into two subsections:
- iOS internationalization, and
- iOS localization.
Before we delve deeper into the topics subsections mentioned-above, let us first have a look at some substantial prerequisites.
Getting Ready For iOS internationalization
First things first, for all the beginners out there, to implement i18n and l10n support for an iOS app, we’ll be using Swift (version 5), the programming language for iOS. We’ll also employ Xcode, the integrated development environment that pulls all the tools needed to produce an iOS app (version 11).
Now, if you’re ready, start off by determining the regions you want to target, and what languages those regions have. In internationalization, these regions are also known as locales. For the purposes of this iOS tutorial, I am going to use English as the base language, French, Chinese (Simplified), as well as German as the target languages for localization. You can add as many languages as you want to your iOS app, depending on both your requirements and target audience. The steps for adding other languages would be exactly the same.
Now that we have discussed the basics, it is time to dive into the subsections mentioned before.
Internationalization (i18n) is the process of making your iOS app adaptable to different locales. From an iOS developer’s perspective, it is the process of making strings externally editable – be it in a storyboard or in code. Furthermore, in order to set dates, numbers, etc. according to the respective locale, you have to use different build-in classes. For example, we can use the “formatting” class to format the dates according to the region, numbers according to the preferred language, and so on. For now, we are going to use the simple setup to get used to the internationalization process.
Recommendation » Always do Internationalization and Localization steps after completing the design and the coding part of your application. Why? Because Xcode will save most of your time by adding strings automatically in the localizable files. If you do these steps before writing the code for your application, you have to manually add all of the strings in their designated files (for localization). Bottom-line is that you should do all the steps of internationalization at the very end. This approach is true if you are using interface builder and storyboards in your project. If however, you are laying out your UI components programmatically, it will be better if you start this process at the beginning of the project to save you enormous time and to avoid omitting any strings for localization.
Note: You are likely to have any of these possible scenarios when trying to internationalize and localize your iOS application. The first case is when the app UI components are completely built out in the interface builder using storyboards or Xib’s.
The second scenario is when the app UI components are built both using storyboards and programmatically in code. And the last one is when the app UI components are built programmatically in code. You can have any of these variations in your app. However, in the demo app, we set up our UI components in storyboards and programmatically in code.
As an iOS developer, you need to take the following steps to internationalize your app with confidence:
Setting Up the Project for I18n
To get started, first, you need to download our starter project on GitHub or you can clone the repository. This is a simple app displaying our solar system, which we will be building upon. It will help us apply the substantial steps in internationalizing and localizing an iOS app. We can apply this process if we are using storyboards, programmatic UI, or a combination of both in building out our UI components. The app is also structured to make it possible to localize not only text but also image assets in our app.
So to get started, run the code on Xcode and your app would look as shown below:
We are now all set to internationalize our app so follow the steps below:
As you can see in the above picture, there are three boxes: red, black, and blue.
- From the Navigator panel, you should first select the root file (.xcodeproj) of your project (in the red box shown above).
- Select the type of project. As you can see, there are two options available. Targets is the default option. You need to change it to Project (in the black box shown above).
- Make sure to check the option “Use Base Internationalization” if it’s not already checked (shown in the blue box above). It’s usually checked by default.
What is “Use Base Internationalization” in Xcode? » Upon creating a new project, Xcode automatically generates files related to localization. When you check the “Use Base Internationalization” option, Xcode transfers the Main.storyboard and LaunchScreen.storyboard into the “Base.lproj” folder for the default language. Our Base language in this tutorial is English, as mentioned in the Decisions section.
Once you have done this basic step, you need to add different languages that you want your application to support. In this tutorial, we are going to use three languages—French, Chinese (Simplified), and German—for localization representing different locales, as discussed in the Decisions section. Let us add the support for these three languages!
Adding Languages for Localization
In order to add languages in your application for Localization (l10n), you need to go to the project Info settings again, and click the “+” button (as shown below):
Xcode will present to you the list of languages you can select from. Let us choose French first! Upon selecting any language (in our case French), Xcode will ask you to choose files and reference language to create your desired language localization (French, in our case), uncheck LaunchScreen.storyboard. Apple allows only static assets in the LaunchScreen and does not support localization in the LaunchScreen.
In the above picture, two things require your attention:
- Reference Language—the Base language in which we have designed our application, which is by-default English (leave it as is!).
- File Types—make sure that all files are set to Localizable Strings.
Click Finish as shown in the screenshot above
Changes in the Project After Language Support
Upon adding support for the French language localization, you will see the following three changes in your project files:
- Xcode will create a folder named “fr.lproj” in your project since we have added support for the French language.
- In that folder, Xcode will create one string file associated with the Main.storyboard that we have selected in the previous step.
- The third change, however, depends upon when you add localization support to your application. If you followed my recommendation mentioned at the top regarding when to internationalize and localize your application, you would see the label presented in your Main.storyboard will be given an Object-ID and added to the Main.strings file.Click on Main.storyboard which is now a folder and you would see the new string file (Main.strings) added as shown below.
We have only one label “Ready, let’s Go !!!” in Main.storyboard. This means that we would have one “Ready, let’s Go !!!” object in Main.strings (French) file with its ObjectID. Check out the screenshot below for the content of Main.strings(French) file.
Add Chinese (Simplified) and German languages as well by following the aforementioned steps.
The steps we have taken so far works perfectly well when we are using only storyboards. How about when we layout our UI components programmatically in code? How do we enable i18n in that case? Well, we have got you covered, you need to create a strings file in Xcode and name it Localizable. Check out the screenshots below:
Select the Strings file and name it Localizable and create the file.
The Localizable.strings file will hold the strings we would want to localize later on. Select the Localizable.strings file you created and navigate to the File inspector. Click on Localize under Localization.
This will display a prompt to select the language of localization. First, we will select our base language English and check the remaining Chinese, French, and German languages respectively from the file inspector as shown below.
Once we have done this, we will now have four Localizable strings files with one being our base language English.
We are almost set to finally localize the app but we still have one thing left, our assets, we want to be able to localize the images for the nine planets we used in the app. As our app shows the images of the nine solar planets we have, we want each locale we support to have images with text that captures their own language.
First, click on the Assets folder (the green box) from the Navigation panel, and select one image of the planets, let’s start with the image of earth.
From the Attributes inspector, click on Localize:
Check all the three languages, French, Chinese, German. Once you have done this, it will create new areas where you would add the respective images for the languages you support when localizing.
You can do the same for the remaining images of the planets.
We are now going to look into the localization part of the application properly.
Localization(l10n) in iOS
Localization, in iOS, is basically the translating process. There are two methods you can use to translate your application.
- Directly in the Xcode (by the developer)
- Exporting Localizable Files (in XLIFF format) for translators
Let’s discuss both of these methods one by one!
First, let’s start with the easy one. Let’s localize our images. The images we will be using are already bundled with the project, we have already prepared the images for the respective languages we want to support. To grab the assets, click on DemoAppAssets.zip from the navigation panel of the demo project and right-click and select Show on Finder, from there, you can easily copy the zipped file to your Desktop and unzip it to have access to all the images.
From the navigation panel, click on the Assets folder. You will see the sections where you will put in images for all the different languages we support.
The blue box section above will be taking images with text in German, and the same applies in the red and black boxes above. From the images you have downloaded, drag in earth image from the German folder to the blue box, from the French folder, drag in earth image to the red box, and from the Chinese folder, drag in earth image to the black box. Do the same for the remaining images of the planets. Once you are done with this, the assets are fully localized.
Now, let’s focus on localizing the text contents we used in our code. We used both storyboards and programmatic UI in this demo app, let’s start by localizing the text contents we added programmatically in code.
Open up Localizable.strings file which is currently empty for now. This file takes in key-value pair of strings which must be terminated with a semicolon (;).
We have two texts to localize: “The Solar Planets” inside the HeaderView, and “Explore” inside the WelcomeController. Inside Localizable.strings (English) file put in these key-value pairs:
"HeaderViewTitle" = "The Solar Planets"; "ExploreButtonTitle" = "Explore";
To actually use this in our code, we need to use the API Apple provided for localization. We will be using the macro
NSLocalizedString(key, comment) which returns a localized version of the strings.
The key will be the one we used in the Localizable.strings, the comment is useful if you want to add additional context that would help your translators.
One thing to note is that you should ensure your string keys are unique and if for any reason you mistakenly used the wrong key when calling
NSLocalizedString(key, comment) , the wrong key you provided will be returned to you as the localized string. You have to be mindful of this.
We have created a String extension in the code that would help make things much easier for us.
Just before we continue, I want to draw your attention to another handy API Apple provided which we can also use while localizing our app. It is
NSLocalizedString(key: String, tableName: String?, bundle: Bundle, value: String, comment: String)
This API becomes useful when you want to split your strings files into smaller manageable sizes especially when you are working on a very large app and you don’t want to have all your localizable strings in one Localizable.strings file.
NSLocalizedString(key, comment)only reads Localizable.strings file by default. For the parameters of the API above, the tableName captures the name of the strings file you created, the bundle is the bundle containing the strings file, the value is the string you want to be displayed in case a wrong key was provided, and the comment is used to provide additional context to the translators.
Now, let’s continue, open String+Extension.swift file to see what we have got there. To Localize strings in the HeaderView file and WelcomeController respectively, replace the “The Solar Planets” and “Explore” with:
"HeaderViewTitle".localized // Replace "The Solar Planets" inside HeaderView with this "ExploreButtonTitle".localized // Replace "Explore" inside WelcomeController with this
We are now good to go, we have done all the hard work. The other part is adding the translated text version for the other languages we support. How do we achieve this? To use Google Translate? No, I don’t recommend that. This is because it might not give you proper translation for the text, you might end up doing more harm than good to your users who may find the translation very offensive. Phrase actually got you covered here and will provide you with the right service to translate your texts by human translators who are experts in the respective languages you want to support.
Since we are working on the demo app, let’s try to translate the text contents using Google Translate as we don’t really care right now, this is not a production app, so nothing to worry about. We will translate the text above in Chinese, do the remaining one for the other languages. Open Localizable.strings (Chinese, Simplified) and put in these strings.
"HeaderViewTitle" = "太阳行星"; "ExploreButtonTitle" = "探索";
We are almost done, but wait, we still haven’t localized the text contents generated for us in our storyboards. Xcode has already done the hard work for us, all we need to do is replace the text contents with our translated versions. We will have to localize the texts in our Main.storyboard. In our LaunchScreen.storyboard, we have a static image, Apple recommends we use a static image here in our LaunchScreen and avoid using strings that might need to be localized here. Hence, we won’t be localizing our LaunchScreen.strings file.
Open Main.strings (Chinese, Simplified) and replace “Ready, let’s Go !!!” with “准备好了，开始吧！”
Gotten to this stage, pat yourself at the back, we did it. We have fully localized our contents both text and image assets.
Now is the moment of truth, let’s test out if this actually works. We will be testing this out in Simulator by changing the language of the application in Xcode. Check below on how you can achieve this.
From Above, click on Edit Scene:
Select Run and click on Options, then change the Application Language in the blue box to Chinese, Simplified. Once done, click on Close and run the project.
Yes, 🙌 we made it, we have localized our app, congrats, it’s well deserved.
Exporting Localizable Files for Translators
In this method, we shall see how to export localizable files for the localizers (translators). To do so, first create a separate folder for Localization (as shown below):
As you can see, there are two folders within the “Localization” folder. “To Localizers” is the folder, where we, being the developers, export our localizable files for translators. “From Localizers” is the folder, from where we would import the localized files from translators to our project.
After creating the folders, go back to our Xcode project and open the root folder Info settings again. From the Editor’s menu, click on “Export for Localization”.
Once you clicked the “Export for Localization” option, Xcode will ask you to save the localizable files to your specified folder as shown below:
As you can see in the above picture that all three languages are selected and will be exported to the “To Localizers” folder in XLIFF format—XML Localization Interchange File Format.
Being a developer, your job is done here! Now you have to wait for the translators to translate the strings present in XLIFF files and send you back in the same format. Once you receive the translated XLIFF files, you should import them into your project using the same Editor’s menu(shown above), but this time, select the “Import Localizations” option.
Recommended Method for Internationalization
The first method in localization – within Xcode – apparently seems nice and dandy, but let us ask ourselves three basic questions:
- Do we, being the iOS developers, really have a command over the languages of all the locales that support Apple Services?
- Can we depend on Google Translate for precise translations?
- Is there any less time-consuming and more efficient solution?
The answer to the first question is definitely “no”. I can speak only four languages. How many languages do you speak? Feel free to let us know in the comments below! Do you trust Google Translate to translate accurately for you? The answer is probably no.
A More Efficient I18n Solution
Now, you must be wondering, “If not Google Services, then what?” Well, would not it be better if we would have access to native translators of different locales in one place for precise translations? Would not it be awesome if you only needed to export XLIFF files, without worrying about the translation process?
Phrase, a comprehensive and developer-friendly translation management platform, supports XLIFF files and can sustainably aid your iOS i18n and l10n efforts! Jump right into Phrase’s Getting-Started Guide to iOS internationalization to see how it can help you!
I hope this article helped you get the ball rolling and made you more confident about adding internationalization and localization support to your iOS app.
If you want to learn even more about iOS internationalization, feel free to check out the following articles: