How to localize SwiftUI elements in Xcode 12

Update: It got easier! See our complete SwiftUI localization tutorial here with Xcode 13

SwiftUI localization is easy… right?

TL;DR Using NSLocalizedString() is still the best way to localize in SwiftUI.

Sometimes Apple gets localization so right that it “just works”. At first glance, SwiftUI localization in Xcode seems like that. For example, look at this simple SwiftUI localization example:

import SwiftUI

struct ContentView: View {
    var body: some View {
Text(“SwiftUI Localization Tutorial”)
}
}

Did you notice any special localization code for SwiftUI yet? There was none. Because in Xcode 12, SwiftUI automatically includes literal text inside of Text() labels in all localization files. Just select Editor -> Export for localization… and the text “SwiftUI Localization Tutorial” will be included for your translators.

You can even turn off this automatic localization in SwiftUI using the verbatim initializer:

Text(verbatim: “SwiftUI Localization Tutorial”)

This text will be displayed in English no matter which language the user chooses. (This is a good way of leaving untranslatable elements, like your app name, out of the Xcode localization export.)

SwiftUI localization is incomplete

That’s the end of “easy” though. Most developers get confused as soon as they pass a variable to the Text() label, however:

var label:String
Text(label)

This won’t get localized. Xcode assumes by default that variables should not be localized. This is explained in the SwiftUI documentation from Apple. One way around this is to explicitly convert the text to a localized string key:

Text(LocalizedStringKey(label))

If you use LocalizedStringKey, Xcode does look for a localized string to replace the variable. But—and it’s a big but—the text won’t get exported for localization automatically. You must add it manually to a Localizable.strings file at the top of your project hierarchy.

There are other types of hard-coded strings that must ALSO be localized into every language. For instance, text inside a Button() call or navigationTitle().

Button("Go to Localization Tutorial", action: goTutorial)

Text inside of Button() labels need to be localized, just like the text blocks in previous examples. But localizing buttons doesn’t come “for free” with SwiftUI Localization. Why? I have no idea, but hope it will be rectified in future Xcode and SwiftUI localization updates.

SwiftUI localization using NSLocalizedString

The easiest way to localize all hard-coded strings in SwiftUI is the same way we localize text in Swift generally. Use the NSLocalizedString() macro:

Button(NSLocalizedString("go.button", value:"Go to Localization Tutorial", comment:"Takes user to the tutorial page"), action: goTutorial)

The NSLocalizedString() macro lets you choose a unique key for the text, include the default (English) value, as well as add a comment for the translator. These texts inside NSLocalizedString will be exported into your localization files! For a full tutorial check out:

iOS Localization Tutorial

One last note about comments: Comments are important because your translator might not be able to “see” the text in context. Telling a translator the text is a button helps a lot. A headline, for example, might be translated differently in many languages.

Further reading:

SwiftUI Localization Tutorial

Share this article