Swift Localization: Building Multilingual Apps

Unlock the power of Swift localization to expand your app’s audience and enhance user experience.

Vikram Kumar
6 min readNov 1, 2023

What is Localization?

Localization is the process of adapting your app to different languages and regions. This involves translating user interface elements, text, and content while also formatting numbers, dates, and currencies according to regional conventions. By localizing your app, you make it more accessible and user-friendly to a global audience, respecting their linguistic and cultural preferences.

Photo by Jess Bailey on Unsplash

The Importance of Localization

Localization is essential for various reasons.

  • Global Reach: Localization broadens your app’s reach, appealing to a more diverse audience and potentially increasing your user base.
  • Enhanced User Experience: Users are more likely to engage with an app in their native language, leading to better user satisfaction and retention.
  • Cultural Sensitivity: Localization demonstrates respect for the cultural differences and linguistic preferences of your users, making them feel more comfortable and connected with your app.

Getting Started

1. Preparing Your Project

Detailed Explanation: To prepare your project for localization, follow these steps:

  1. In Xcode, navigate to your project settings.
  2. In the “Localizations” section, add the languages you want to support.
  3. Xcode will create language-specific .lproj folders for each language, which will contain localized resources.
Xcode screenshot

2. Localized Strings

Localized strings are stored in .strings files named Localizable.strings. Each language version of this file contains key-value pairs, with keys representing the text in your app and values as the translated content.

Example:
Assume you want to display a welcome message in your app in different languages. Your Localizable.strings file for English might look like this:

English (Localizable.strings)

"welcome_message" = "Welcome to our app!";

For French, you would create a Localizable.strings file in the “fr.lproj” folder:

French (Localizable.strings)

"welcome_message" = "Bienvenue dans notre application !";

3. NSLocalizedString

The NSLocalizedString function is a key component of localization in iOS and macOS app development using Swift. It's used to load and display localized strings in your app, allowing you to present content to users in their preferred language or dialect. This function is part of the Foundation framework in Apple's development environment.

Here’s how the NSLocalizedString function works:

let localizedString = NSLocalizedString("key", comment: "")
  • "key": This is the key or identifier used to look up the localized string in the appropriate .strings file for the user's language. It's a reference to the actual text you want to display in different languages.
  • comment: The comment is an optional argument and is typically used for documentation or context. It helps translators understand the usage of the key in your code. It's a good practice to provide a clear comment.

The key specified in NSLocalizedString is associated with a corresponding localized string in .strings files. These files store the translations for different languages, and the correct string is retrieved based on the user's language settings. The NSLocalizedString function automatically selects the appropriate translation to display.

When you use NSLocalizedString with the key "welcome_message", the function will return the appropriate translation based on the user's language setting. If the user's language is set to English, it will return "Welcome to our app!"; if set to French, it will return "Bienvenue dans notre application!".

The NSLocalizedString function is a powerful tool that simplifies the process of implementing localization in your iOS and macOS apps, making it possible to provide a consistent and user-friendly experience for a global audience.

4. String Extension Helper

A string extension helper in Swift is a custom extension on the String data type that adds additional functionality to strings. This is a powerful feature of Swift that allows you to extend the behavior of built-in types, like strings, without modifying their original code. Creating string extension helpers is a common practice when working with localized strings or adding convenience methods for string manipulation.

Here’s how you can create a simple string extension helper for easy localization in Swift:

extension String {
func localized() -> String {
return NSLocalizedString(self, comment: "")
}
}

In this example:

  • extension String { ... }: This defines a new extension for the String data type.
  • func localized() -> String { ... }: This is a function you're adding to all string instances. It's named localized() and returns a string.
  • return NSLocalizedString(self, comment: ""): Inside the localized() function, you use NSLocalizedString to look up the localized version of the string based on the string itself (the instance on which you call localized()) and an optional comment. It returns the localized string for the current language setting.

Now, you can use this extension to simplify the localization of strings throughout your code:

let welcomeMessage = "welcome_message".localized()

With the localized() extension, you no longer need to use NSLocalizedString directly every time you want to retrieve a localized string. It makes your code cleaner and more readable.

5. Show localization from saved language using UserDefaults

Below extension allows you to perform localized string lookups based on a selected language stored in UserDefaults and also provides a way to handle localized strings with dynamic arguments for string interpolation.

This extension on the String data type is an excellent example of a more advanced localized string helper.

extension String {
func localized() -> String {
// Retrieve the selected language from UserDefaults
let langKey = UserDefaults.standard.string(forKey: "selectedLanguage")

// Try to find the corresponding .lproj folder for the selected language
if let path = Bundle.main.path(forResource: langKey, ofType: "lproj") {
// If found, create a bundle for that language
let bundle = Bundle(path: path) ?? .main
// Use NSLocalizedString with the specified bundle
return NSLocalizedString(self, tableName: nil, bundle: bundle, value: "", comment: "")
}

// If the language is not found, use the system language (fallback)
return NSLocalizedString(self, comment: "")
}

func localized(with arguments: [String]) -> String {
// Use String format to interpolate the localized string with dynamic arguments
return String(format: self.localized(), locale: nil, arguments: arguments)
}
}

Here’s how you can use these methods:

  1. localized(): This method retrieves the selected language from UserDefaults. It then attempts to find the corresponding .lproj folder for that language. If found, it creates a Bundle for that language and uses NSLocalizedString with this bundle to retrieve the localized string. If the language is not found, it falls back to using the system language. This is a handy way to allow users to choose their preferred language within your app.
  2. localized(with arguments: [String]): This method allows you to interpolate dynamic arguments into a localized string. It first calls self.localized() to get the localized version of the string and then uses String format to replace placeholders in the localized string with the provided arguments. This is particularly useful when you have placeholders like %@ or %d in your localized strings.

Assuming you have a Localizable.strings file with the following entries:

// English (Localizable.strings)

"welcome_message" = "Welcome to our app, %@!";
"items_count" = "You have %d items.";


// French (Localizable.strings)
"welcome_message" = "Bienvenue dans notre application, %@!";
"items_count" = "Vous avez %d éléments.";

And you have a UserDefaults key "selectedLanguage" set to "fr" to switch to French.

Here are examples of how to use your extension methods:

  1. Using localized() to Retrieve Localized Strings:
// Assuming "selectedLanguage" is set to "fr" (French)

let welcomeMessage = "welcome_message".localized()
print(welcomeMessage) // Output: "Bienvenue dans notre application, %@!"

// If "selectedLanguage" is not set or "fr" is not found, it falls back to the system language.
let systemWelcomeMessage = "welcome_message".localized()
print(systemWelcomeMessage) // Output: "Welcome to our app, %@!"

2. Using localized(with arguments: [String]) for String Interpolation:

let itemCount = "items_count".localized(with: ["5"])
print(itemCount) // Output: "You have 5 items."

// You can use the same method for multiple arguments, such as:
let gretting = "welcome_message".localized(with: ["John"])
print(gretting) // Output: "Welcome to our app, John!"

These examples demonstrate how to use your localized() method for retrieving localized strings based on the selected language and localized(with arguments: [String]) for interpolating dynamic values into localized strings. This extension provides a convenient way to manage localized strings with user-selectable languages and dynamic content.

Conclusion

To conclude, Swift localization is a powerful tool for making your app accessible to a global audience. By following the steps mentioned in this article and using string extension helpers, you can streamline the localization process. Ensure you respect cultural and linguistic differences to provide a seamless experience for users worldwide.

This article equips you with the knowledge and tools to create multilingual apps with Swift.

Happy coding!

--

--

Vikram Kumar
Vikram Kumar

Written by Vikram Kumar

I am Vikram, a Senior iOS Developer at Matellio Inc. focused on writing clean and efficient code. Complex problem-solver with an analytical and driven mindset.

No responses yet