Internationalization (i18n) in Swift: Complete Guide for iOS and macOS
Internationalization (abbreviated as i18n) is the process of designing an application so that it can be adapted to various languages and regions without changing the source code. For developers on Apple platforms (iOS, macOS, watchOS, tvOS), Swift offers a powerful yet elegant set of tools. In this article, we will thoroughly examine how to set up i18n in your Swift project using Apple's built-in mechanisms.
Why is i18n critically important?
Even if your application is initially created in one language, internationalization should be built in at the architecture stage. This allows you to:
- Expand your audience: Users from different countries prefer applications in their native language.
- Simplify localization: Proper i18n turns adding a new language into a simple file operation.
- Avoid hardcoding: All strings are moved to separate resources, improving code readability and maintainability.
Main Tool: NSLocalizedString
The heart of internationalization in Swift is the NSLocalizedString macro. It looks up a string in localization files (.strings) and returns the translated version. If no translation is found, the key (usually an English string) is used.
// Example usage in Swiftlet welcomeMessage = NSLocalizedString("welcome_message", comment: "Greeting on the main screen")label.text = welcomeMessageIt is recommended to always provide a comment — it helps translators understand the context.
Structure of Localization Files
In Xcode, languages are added via Project Settings > Info > Localizations. After that, folders xx.lproj are created (e.g., en.lproj, ru.lproj). Inside them are stored:
- Localizable.strings — the main file with "key" = "value" pairs;
- InfoPlist.strings — for localizing the app name and system strings;
- Storyboard.strings — an automatically generated file for interfaces created in storyboards.
Localizable.strings Format
The file has a simple syntax:
// English (en.lproj/Localizable.strings)"welcome_message" = "Welcome to our app!";"login_button" = "Log In";
// Russian (ru.lproj/Localizable.strings)"welcome_message" = "Добро пожаловать в наше приложение!";"login_button" = "Войти";Important: Strings end with a semicolon. The file encoding must be UTF-8 or UTF-16.
Formatting Strings with Parameters
Often you need to insert dynamic data into a string (username, item count). For this, use String(format:):
// In Localizable.strings:"items_count" = "You have %d items.";"user_greeting" = "Hello, %@!";
// In Swift code:let count = 5let itemsText = String(format: NSLocalizedString("items_count", comment: "Number of items"), count)
let userName = "Alexey"let greeting = String(format: NSLocalizedString("user_greeting", comment: "User greeting"), userName)For plural forms support (1 apple, 2 apples, 5 apples), use StringDict (.stringsdict files).
Working with XLIFF for Translators
Apple supports the XLIFF format (XML Localisation Interchange File). This is an industry standard for exchanging translations. In Xcode, you can export all strings to an XLIFF file, give it to a translator, and then import it back.
// Terminal command for export:xcodebuild -exportLocalizations -localizationPath ./translations -project YourProject.xcodeproj
// Import of completed translations: