Localization is the process of adapting your app to different languages and cultures. Even though it is a mostly straightforward and streamlined process, it is often overlooked in the development process, which can result in longer development times due to typos in the text, incorrect images displaying in wrong locales, etc. This blog post aims to give you a better understanding of the iOS localization process and will cover a handful of best practices you can start using.
iOS Localization Best Practices
Determine if localization is even necessary
Not every product needs to be localized. There are some apps that are always going to pertain to only one specific market, and in that case, there’s really no need to spend any time or resources on localization. First, you should identify if there’s a real need to localize and then start planning for the process if you deem it necessary.
Here is some criteria to help you determine if you need to consider localization:
- If the app will be released to different markets, you will need to localize for their different languages, currencies, number and date formats, etc.
- If you want to market your app to different ethnicities, religions, ages, etc., the best approach is to provide custom-tailored content for those groups via localization.
- If you don’t have enough resources to implement localization fully and properly, you may want to provide a single version of the app to specific markets first, then consider expanding later.
Localization can sometimes be a long and complicated process. Not only does it include the need for translation of text, but there are also other teams that are often involved in the process, such as marketing and design. For example, if you’re localizing an iOS app for a specific language, country, or culture, you’ll need to verify that all of your designs match that language by making the necessary modifications. Then you will need to market your app to that group. Planning ahead is a great way to ensure you cross off all of the required considerations when it comes to localization.
On the development side of things, you can plan ahead by structuring your code to make it more localization friendly—a process we will cover in a few paragraphs.
Use test plans
Testing is probably the most important phase of app development. You should design your tests around the localization of your app, so that every time a bug fix or new feature is released, you can rest assured that it will work in all of your supported markets.
Adapt your app
There are a lot of things to consider when adapting your app for localization. Some languages can take up to 30% more screen space than others, so take this into account:
- Leave plenty of space for languages that take up more screen space
- Adapt your content to align with target markets
- Convert your units of measurement (calories, currency, length, etc.)
How to Properly Localize your iOS App
Now it’s time to examine how to support better localization practices from a development perspective.
No more management of strings files
Historically, iOS localization required developers to create multiple strings files, wherein you had to associate your localized text with a key so you could retrieve the text later in code by using said key (see image above).
Now, developers are able to represent localized text in a project’s code by encapsulating said text into swift Structures. This enables a Type Safe way of retrieving localized text without the risk of spelling errors.
In the image above, you can see how every text that is required by the app is encapsulated within a structure named Localization and also within sub-structures representing different features or screens for the app.
Centralizing your localized strings and assets
The main idea for this whole project is a really simple one: centralize everything you need localized, since it’s mostly static anyways, and namespace it. I suggest creating a localization struct and then sub-structs for each component of the app that will contain the localized strings. This way, you can organize your code by putting your localization in different folders, as opposed to using one big file or extending the localization structs.
NOTE: In Xcode 13, you can use String(localized:) to get your strings automatically from the strings files. On Xcode 12 and earlier, you should just use string literals.
Protocol for localization users
You normally want your code decoupled from other logic. To help with this, I created a really simple protocol that defines a single associated type and allows you to declare only the strings and assets you need on the object you need.
To use it, simply extend the object where you need localized strings and assets and declare a structure with the same name of the associated type in your protocol. Inside your structure, define the strings and assets you need and assign them the values from the Localization namespace.
Helpful Xcode 13 utilities for iOS localization
Xcode 13 introduced a change where TextView and other components in SwiftUI can take localized Strings of type LocalizedStringKey, allowing developers to see localizables in the previews instead of having to run the app.
For this, you only need to pass the locale environment variable with the language identifier.
Importing and exporting localizations with Xcode 13
When using Xcode 13, you can extract your strings into a localization catalog by going to Product → ExportLocalizations.
You will get a localization catalog that you can then send or modify by adding localization to the respective asset, like in the following image:
After you have performed the localization process, you can go to your Xcode and import it by going to Product → Import Localizations. Then, Xcode will generate all the required strings files without the developer having to touch them.
Using test plans
Finally, using test plans allows you to create configurations in which you can define your localizations. For every scheme using the test plan, you can run your tests in each language or in all languages one after the other.
Good iOS localization practices can sometimes be overlooked, but when implemented correctly, can help us avoid having to refactor code, duplicated or unused text, and can ultimately reduce extra development time that could be better used for other efforts.
The important thing to keep in mind is to not use hardcoded strings and instead use a type safe approach by implementing your localization inside structs or enums with static variables. This way, everything localization-related can be centralized and reused.