Introduction to SwiftUI Localization tutorial
Tweet Updated June 21, 2021
SwiftUI Localization How-to
How to Localize in SwiftUI
Localizing in SwiftUI follows the same pattern as localization of all apps in Xcode.
- 1. First, you need to identify the texts to be translated.
- These are your user-facing text labels, buttons, and other visible parts of your app's user interface.
- 2. Then you need to add them to a localization file for your translators to work on.
- At runtime, your iOS/Mac app will show the right translation to the user based on their own language preferences.
Updated for Xcode 13 This was a major update for localization, and it's highly recommend you update if you are using SwiftUI. If not, the previous methods outline also still work.
View our blog post: Xcode 13 and Swift Updates from WWDC21
Localization Q&A by Babble-on
More questions:Translate that SwiftUI app
Once you've completed this tutorial to internationalize your app, please let us translate your strings!
Bookmark this page and come back for a free price quote.
Categories
Xcode 13 and SwiftUI
Xcode 13 brings some big changes to localization in SwiftUI. The Swift Compiler now does the heavy lifting of extracting the strings, and the amount of work you need to do is trivial. It gets much closer to the famous “it just works” motto.
If you're coding in SwiftUI, it really helps to upgrade to Xcode 13 and follow this method.
(Of course, if you can't upgrade just yet, follow Method 2 or 3 below for now. While a bit more work, the results are the same.)
-
Turn localization settings on
In Xcode, choose your project, then Build Settings and filter the list for Localization settings. Turn everything to Yes, specifically:
Localization Export Supported
Localization String SwiftUI Support
Use Complier to Extract Swift Strings If you created your project in a previous version of Xcode, the Use Compiler to extract Swift strings is likely set to No, and it's critical we fix that before we go further.
-
Add your languages
Now head over to the Info panel. Base localization should be turned on by default (if it's not, check the box), and add at least one new language by clicking on the icon.
Base internationalization places all your shared resources in the same place. Then, it creates folders and copies of resources that need to be different for each language. Mostly that includes the .strings files with the translation of each piece of text in your app. But, should you choose, it can also mean different image resources. Maybe you want a French flag to appear on your French localization, for instance.
-
Use Text() with your string literals
Wrap your user-facing texts with Text()
Button(action: signin) { Text("Sign in", comment: "Signin button link") }
-
Custom views need LocalizedStringKey too
If you're using custom views and methods that take string literals, they won't automatically be exported for localization unless you make one last change.
Change String to type LocalizedStringKey.
import SwiftUI struct CardActionButton: View { var label: LocalizedStringKey //...
In Xcode 13, it works with string interpolation, too.
Text("Please wait \(seconds)",
comment: "Countdown message with seconds until done")
Remember to always add a comment
to explain to the translator where in the UI this text appears. Is it a button, or a headline? What will replace the variable?
That LocalizedStringKey type is the magic that makes SwiftUI localization in Xcode 13 so easy. The first argument to Text() is the LocalizedStringKey type, and all LocalizedStringKey texts are automatically exported for localization by the Xcode 13 compiler.
You're all set now, and ready to export your texts for your translators.
Skip ahead to Exporting localizations into XLIFF in Xcode.
Method 2: Using Localizable.strings for SwiftUI Localization
If you're using an earlier version of Xcode (12.5 or earlier), you can accomplish the same localization in SwiftUI by manually creating a Localizable.strings file.
-
Create Localizable.strings
In Xcode, choose from the File -> New -> File… and select a Strings file. There are two critical points here:
Name this file Localizable.strings — Xcode specifically looks for this name!
Make sure to save this file at the Project level, not in a subfolder.
-
Use LocalizedStringKey()
Wrap your user-facing texts with LocalizedStringKey()
Button(LocalizedStringKey("signin.button"))
-
Add English text
Open your Localizable.strings file, then add the key and English string:
"signin.button" = "Sign in";
- Left side
- This is the key you used in your SwiftUI code. It should be unique.
- Right side
- This is the English text to display. Your translator will translate this text.
Note the formatting with straight quotes "", an equal sign = and a semicolon ; at the end. All are required!
-
Don't forget comments
You can add an optional /* comment */ on the preceding line, which will help the translators:
/* Button to log in user */ "signin.button" = "Sign in";
It even works with interpolated strings like .navigationBarTitle(LocalizedStringKey("\(user.name)’s Page"))) but make sure to use variable substitution in the strings file:
/* %@ is the user's first name */ "%@’s Page" = "%@’s Page";
If you're unsure what to use for variable substitution, type it into the debugger:
po LocalizedStringKey("My number: \(8.2)")
Method 3: Using NSLocalizedString() for SwiftUI Localization
Wrap text in NSLocalizedString()
Let's start with a simple button, which might look like this in your SwiftUI code:
Button("Sign in", action: signIn)
We definitely want this button localized, so we add NSLocalizedString() around the literal text
Button(NSLocalizedString("signin.button", value:"Sign in", comment:"Button to log in user"))
Let's break that down:
- "signin.button" — A unique key for this string. Use something descriptive. That helps you and the translator.
- value: — This is the "default" text iOS will show in your development language (likely English), OR if there is no translation available in the user's language yet.
- comment: — Text that will help the translator understand the context.
You'll need to do this for every string in your SwiftUI app that a user might see and that requires translation.
NSLocalizedString() works with formatted strings or variables as well.
var fruits = ["Apple", "Banana", "Papaya", "Mango"] Text(String(format: NSLocalizedString("fruit.count", value: "%d Fruits", comment: "Headline, number of fruits"), fruits.count))
Note that you need to use a variable substitution like %@ or %d in the localized string.
Always include a unique key and a helpful comment for the translators. Since you will need to add the NSLocalizedString call to every string a user sees, take an extra moment to tell the translators what this string is for. Remember, they'll be seeing it totally out of context, and your helpful hint is all they have! Knowing that a text is a title or a button, a noun or a verb, can be very helpful. Also make sure your key is absolutely unique. That will ensure that you can translate a string like "Clear" as both a button to remove text, AND as an adjective describing a transparent color. In other languages, these two words are certain to be different!
Exporting localizations into XLIFF in Xcode
In Xcode, Apple has embraced the XLIFF format for handing off to your translation team
Xcode has a very useful import & export feature for localization. Now that you've wrapped all of your texts in NSLocalizedString or LocalizedStringKey, it's easy to export it into a file format your translators can use.
(XLIFF is a standard XML-format supported by most translation software, including ours.)
Importing and exporting localizations with XLIFF
-
Export For Localization
Select your project from the File navigator. Then choose the menu item Editor > Export For Localization….
-
Save the Development Language
In the Save window that appears, select where to save the export. Generally speaking, as translators, we only need the Development language, which is usually English. But if you have existing translations to share, you will also want to send those. You can export any language from the list of available ones for your project.
And, there you have it! Your app will soon be multilingual. You have all the files you need to send to your iOS/Mac localization team!
-
Import the translations
Your translators should return to you one file for each language using the language code as its name. That is, for French you'll receive an
fr.xliff
file, for Chinese, you'll get back something likezh-Hans.xliff
.Import the files back into Xcode using the menu command Editor > Import Localizations…. Xcode will display a window with the differences between your existing files and the ones your translators have sent you. Press the Import button to finish.
New since Xcode 10: Xcode will now export even more stuff in a folder it called an Xcode catalog, or .xcloc
. In addition to the xliff file, it also exports some Source context (storyboards) and creates a Notes folder where you can put some screenshots for your translators or other instructions.
This is when your translators work…
Previewing translations in SwiftUI
One of the benefits of SwiftUI is live previews. You can preview your translations as you code thanks to SwiftUI's environment variables.
struct ContentView_Previews: PreviewProvider {
static var previews some View {
ContentView()
.environment(\.locale, .init(identifier: "en"))
}
}
Now, by changing that identifier to "es" for Spanish or "zh" or Chinese, you can see your translators' work live in the Xcode simulator preview!
Create a free account in our developer portal to help test out your localization, get free price estimates, and expert advice
See also:
- Language Codes
- Complete list of ISO-639 language codes to use for your iOS app. Use these to name your xx.lproj folders.
- iOS Glossary
- This page contains many common translations for iOS terms, including things like Settings, Tap, etc.
Pseudolocalization — testing you've found every string
Once you've finished preparing your .strings file you're probably having doubts that you actually managed to find every hard-coded string in your app. What about those error messages or that plug-in you use? Well, there is a quick way to check. It's called pseudolocalization!
Plus get free cost estimate
Essentially, you use a program to substitute all the English (source) phrases with a fake language. Load up this gibberish Localizable.strings file into Xcode and then run your app. Check every screen and make sure all the text appears as the pseudo-localized text rather than your original. If you can't spot any missing strings, you're good to go.
Tip: Pseudolocalization is also a great way to make sure you've left enough room in your GUI for other languages. A common rule of thumb is that non-English languages are 30% longer, so tiny buttons and titles may not fit when you localize. Pseudolocalization can help you spot those cramped spaces too!
Start translating your app right away using this free Multilingual iOS Term Glossary. It contains common translations for iOS terms, including things like Settings, Tap, etc. in a dozen languages.
Multilingual iOS applications are what we do
Talk to a real translator.
Interested in professional iOS localization from a team that cares about making apps awesome? Unlike automated or cloud translation services which will translate your "bold" text as brave and "Archive" as a noun without considering it might be a verb, Babble-on is a dedicated team of translators that put as much care into localization as you do into app development.
You can talk to us about your project the whole way through, not just upload your strings and cross your fingers.
We'd love to help get your app ready for localization.