iOS app Internationalization(i18n) using Swift — Part1
While building an app, who doesn’t want to scale their app across the globe and make their app to be available in various local languages. But how one can achieve it, the answer is Internationalization.
Are you developing an iOS application, but you do not know how to internationalize and localize your iOS app? If the answer is yes, then you are at the right place. In this article, we will see how to setup Internationalization and Localization in an iOS application using Swift.
This article will elaborate different approaches to add internationalization support in an iOS app and will also look into its implementation via code.
- Internationalization vs Localization
- Setting-up the project for i18n
- How do I add additional languages support to my app?
- Localizing the Storyboards
- How do I localize strings in my Swift code?
- Consequences of this approach
- What’s next to do ?
A developer or an individual who is new to this internationalization concept often get confuse between these two words “Internationalization and Localization”. These are different but interconnected concepts.
So, what does these basically means? What’s differences between them?
Internationalization (i18n) is process of making our app adaptable to different languages and regions. On the other hand, Localization (l10n) is process of translating our app to different languages.
Internationalization is abbreviated as “i18n” as there are eighteen number of characters between “i” and “n”. Similarly, Localization is abreviated as “l10n” as number of characters between “l” and “n” equals ten.
Setting-up the project for i18n
Here’s a starter-project for you so that we can jump directly to the i18n implementation. Before that, let me explain you the project structure.
The starter-project has a very simple layout, has only three view controllers: SigninViewController
, SignupViewController
and a WelcomeViewController
and a singleton class KeychainHelper
to manage KeyChain services for authentication.
On the initialization of app, user lands on the “SignIn” page, where he/she has option to either sign in or go to “SignUp” page. On successful sign in, user gets redirected to “Welcome” page.
In this project, I have used
KeyChain
services for data encryption and authentication. Read more about it here.
Download and run the starter-project and go through the project once to understand it. Now, let’s start our i18n implementation.
How do I add additional languages support to my app?
From the Project Navigator, select the project name InternationalizationDemo
, make sure you are on Info segment. Then check the Use Base Internationalization
and click on add +
button.
Choose Hindi (hi)
and for now let’s check both storyboards.
Changes in project after adding a language
After adding a supported languages, you’ll realize some changes in your project. Let’s discuss these changes, and what it means for our goal of localization.
• Language folders: Xcode will generate hi.lproj
direcory that will contain Main.strings
for Hindi.
• Storyboard: Main.storyboard
should now be a folder containing the base Main.storyboard
and Main.strings
of supported languages (Hindi here).
•Main.strings
: Each object(labels, buttons,…) are added in this file with an unique ObjectID. Don’t directly change this ObjectID for any item.
Localizing the Storyboards
Click on Main.strings(Hindi)
to open it in the editor. You should already have an entry for the Sign in to your account label which will look something like this:
/* Class = "UILabel"; text = "Sign in to your account"; ObjectID = "61H-Ar-Y7e"; */
"61H-Ar-Y7e.text" = "Sign in to your account";
Replace the English translation with the Hindi translation. Do the same for all other items. Your Main.strings(Hindi)
will look like this:
/* Class = "UILabel"; text = "Sign in to your account"; ObjectID = "61H-Ar-Y7e"; */
"61H-Ar-Y7e.text" = "अपने अकाउंट में साइन इन करें";
Now let’s run the application in Hindi to see if our localization worked. By default, every time you run the application, it uses the base language. You can run your application using different locales by Option + Clicking on the (Play) Start active scheme button, then going to Run → Options → App Language → Change to a supported language (Hindi in this case) → Click Run.
Our app looks like this after adding language support in Hindi.
How do I localize strings in my Swift code?
If you go to the Welcome page, you will notice that the welcomeLabel
is not localized because we are programmatically adding the code here welcomeLabel.text = “Welcome \(user ?? “”)".
So, how do we localize our swift code ?
• Select File → New File → search for Strings File → keep the name Localizable as default.
• Xcode will generate Localizable.strings
file. In the file inspector, you will see localization panel. Click localize and select “Localize”.
• Again, in file inspector, check Hindi in localization panel. Xcode will generate two Localizable.strings
files for both English and Hindi.
We now have two localizable.strings file — one for the base language and other one for the Hindi.
A .strings file stores key-value pairs, just like a Dictionary
. Conventional practice uses the base language translation as the key. The file has a specific, but simple, format:
"KEY" = "CONTENT";
Subsequently, let’s add the key and value pair text used in the Localizable. strings. Below is an example where I added the localization for welcomeLabel
// Localizable (English)
"Welcome %@" = "Welcome %@";
// Localizable (Hindi)
"Welcome %@" = "स्वागत है %@";
NSLocalizedString(_:tableName:bundle:value:comment:)
is the primary tool you use in your code to access these localized strings. The tableName
, bundle
, and value
parameters all have default values so you normally specify only the key
and the comment
. The comment
parameter is there for you to provide a hint to translators as to what purpose this string serves in your app’s user experience.
Let’s say we have a key-value pair in .strings file as
“welcome rohit” = “स्वागत है रोहित”;Here, we can update the text of
welcomeLabel
usingNSLocalizedString(:)
to make it localizable.welcomeLabel.text = NSLocalizedString(“welcome rohit”, comment: “welcome”)
💡 We can include format specifiers in either the key or the value portion of the string to allow you to insert real data at run time.
Open WelcomeViewController
and add the following code in viewDidLoad()
method.
override func viewDidLoad() {
super.viewDidLoad()
let formatString = NSLocalizedString("Welcome %@", comment: "welcome user")
welcomeLabel.text = String.localizedStringWithFormat(formatString, user!)
}
Now, run the app and you will see that our welcomeLabel
in WelcomeViewController
is now able to localized as per the selected language. Also, the user details in welcomeLabel
dynamically get updated since we added format specifiers while localizing it.
Consequences of this approach
Now, we have completed the i18n implementation and our app is ready for both Hindi & English (base) language. But, there are some consequences in the approach we have taken for this implementation.
Let’s take a scenario, Ram is an iOS developer working on a large and a complex app and now he wants to add i18n support for multiple languages (let's say five different languages). He take the above mentioned approach for the implementation. What will happen next ?
• Xcode will generate fiveMain.strings
forMain.storyboard
localization and Ram will have to manually add translated strings for all objects (labels, buttons,…).
• Same this have to be done also for.xib
files.
• High changes of making mistake of altering objectID.
• A very time consuming and an inefficient approach.
What to do next ?
In the next continuation part of this article, we will look into another approach to overcome these consequences. Also, we will also learn about how to programmatically add language switching.
Here is the github link for the completed project using the above approach.
You can find next part here.
Thanks for Reading!
If you liked this article, please share and 👏 so other people can read it too :)