Xcode 13 and Swift Localization

Everything new, shiny, “just works”, and not-so-great

WWDC 2021 brought Xcode 13 and Swift 5.5, the biggest advances to localization we’ve seen for a few years. These are real improvements that will make localization easier for developers. And anything that makes it easier for developers benefits translators and international users. 🥳 🎉 🎊

All of these changes in localization require you to adopt the latest version of Xcode 13 and Swift. That may be a dealbreaker for some, but if you’ve got Swift code, I highly recommend it. The improvements include: localized Attributed Strings, improved Formatters, and something amazing (?) called Automatic Grammar Agreement.

Here’s a breakdown of all the new stuff baked into Xcode 13 localization.

Localized Attributed Strings

Formatting text and adding links has always been a pain point in iOS and Mac localization. Many developers give us broken sentences to localize because they want to apply specific formatting (bold, italics, etc.), or include a link. Localizing plain HTML with formatting and links, by contrast, is straightforward:

Please contact us <strong>first</strong> at <a href="mailto:localize@ibabbleon.com">Support</a>

In the past, formatted or Attributed Strings, in iOS/Mac development were complicated. Worse yet, Attributed strings were not localizable. (In fact, some developers would mark strings in Xcode as Attributed just so they would not export for translation!) In the Localizable.strings file, we would get things like:

"Please contact us "
"first"
" at %@"

The developer would then merge the translations together in code, add the formatting often to the wrong word, and insert the link. But grammar and word order are different in other languages, and the translated result was godawful imperfect.

New in Xcode 13 and Swift 5.5, Attributed Strings are:

  • localizable
  • can include string interpolation
  • take advantage of Markdown formatting
  • export automatically for localization

You can even convert NSAttributedString to the new format for use in UIKit. And Objective-C got a new NSLocalizedAttributedString macro. Together, these changes mean the translator can localize formatted text easily. Now, we can localize that same formatted text like this:

AttributedString(localized: "Please contact us **first** at [Support](mailto:localize@ibabbleon.com)")

And working with variable values has never been easier. Just pass the values in directly:

String(localized: "Welcome back, \(username)!") 

Xcode has a new setting Use Compiler to Extract Swift Strings to export these texts, including Attributed strings with string interpolation, automatically. It’s on by default for new projects, but your existing projects will have to opt in:

Note that Localized String SwiftUI Support setting is deprecated because of the new Compiler setting.

Formatters

As localizers and translators, we look at dates and numbers differently. International users expect a date or a number to look like it does in their region. iOS and macOS have always allowed users to choose their locale and region, but it is still up to developers to implement these preferences.

Formatters got a lot easier with new Foundation APIs. There are formatters for Date / Number / ISO8601 / Measurement / PersonNameComponent, and more.

Now there is no excuse to show a user the wrong date format!

let locale = Locale(identifier: Locale.current.identifier)
let date = Date()
let now = date.formatted(.dateTime.year().day().month().locale(locale))
// English: Jun 24, 2021
// French: 24 juin 2021
// Chinese or Japanese: 2021年6月24日

Xcode not only orders the date in the way the user expects, but even includes the translations for the month name automatically. One less thing to pay us to translate, and one less headache for the translator to explain how the punctuation or order is wrong in the app!

Combine this with localized Attributed strings, and you can safely format parts of the date. For example:

var dateString : AttributedString {
var now = date.formatted(.dateTime.year().day().month().locale(locale).attributed)
let month = AttributeContainer 
      .dateField(.month)
let color = AttributeContainer
      .foregroundColor(.red)
now.replaceAttributes(month, with: color)
return now
}
// English: Jun 24, 2021
// French: 24 juin 2021
// Chinese or Japanese: 2021年6月24日

Here, all months are in a single color, regardless of where they are in the string, or how many characters they take up.

Automatic Grammar Agreement

As a localization specialist, I want to say “Jiminy, this is amazing!” Teaching a machine to understand grammar is hard. (Am I right, Google Translate?) But then you get down to the details, and it is a little less life-changing. But there is potential, so let’s take a look at Foundations’s new Automatic Grammar Agreement.

A new option in iOS 15 also allows users to set their ”Term of Address” — basically, the user’s gender.

This means that you could write Welcome in Spanish Bienvenido, and have it automatically appear in the correct gender if the user is a man or a woman:

Bienvenido 💁‍♂️
Bienvenida
🙋🏻‍♀️

That’s an improvement, but requires you to use a new custom Markdown format for strings:

"^[Welcome](inflect: true)"

BUT… so far these gender localizations are limited to only Spanish.

There are a lot of females speaking other languages, too, so hopefully Apple gets on that for Xcode 14.😛

The main purpose of Automatic Grammar Agreement, however, is to make the translation of plural and gendered texts faster and easier. In English, you might say:

You have 1 open document
You have 2 open documents

In Spanish, you would need:

Tienes 1 documento abierto
Tienes 2 documentos abiertos

English adds an ‘s‘ to the plural form of ‘document‘. But Spanish adds an ‘s‘ to the translations of both ‘open‘ and ‘document‘. Spanish also requires swapping the word order. Other languages will be even more complicated. Some languages have no plural; others have multiple forms of plural. This is why it is best for Xcode, along with translators, to do the pluralization work, not developers.

Automatic Grammar Agreement proposes letting Xcode add those pluralizations “automatically”. Not only in English, which is pretty easy, but in Spanish, which is harder. Xcode is supposed to understand when the gender of the nouns and adjectives need to change.

For plural items, you would, in theory, need just one line of code, and translations for each word, to translate You have %d open document(s). That is:

"You have ^[\(count) \(document) \(status)](inflect: true)"

and have your translators translate separately, but only one form of:

"You have ^[%d %@ %@](inflect: true)" = "Tienes ^[%1$d %3$@ %2$@](inflect: true)";
"document" = "documento";
"open" = "abierto";

Yet translators would still need to translate the words and reorder them so that the noun (documento) comes before the adjective (abierto). Not much work is saved here, and the complexity has increased.

⛔️ Is this easier than the current method, a stringsdict file? Not really.
⛔️ Is it as powerful? No.
⛔️ Does it work in all languages? Not so far.
🤷‍♀️ Is this future? We’ll have to see.

Apple says this is powered by the same technology that offers autocomplete “suggestions” as you type on the keyboard. Right there that tells us grammar agreement can be remarkably intuitive. It can also be an epic fail. ⚠️

But the main reason not to bother with this quite yet is that Automatic Grammar Agreement is limited to only English and Spanish. At least for now.

Hopefully, Apple can expand grammar agreement quickly, or bring Terms of Address to the stringsdict file.

Xcode 13 is here

Xcode 13 and Swift 5.5 really do make localization easier for developers. The last feature worth mentioning is that Xcode has an xcloc editor built in. Xcloc is the package of translation files, screenshots, and notes you send to your translators when you Export Localizations… from the Product menu. It isn’t an amazing translation editor, but it can help you add quick comments or screenshots, or review the translations we send you.

So that’s Xcode 13 localization in a blog post! While I would not recommend Automatic Grammar Agreement until it supports more languages and is more fleshed out, I highly recommend adopting the new AttributedString, Formatter APIs, along with the Use Compiler to Extract Swift Strings. All in all, it’s a big year for localization in Xcode, and that’s good news for your international users.

🇸🇦🇷🇺🇷🇴🇩🇪🇮🇹🇬🇷🇻🇳🇹🇷🇰🇷🇯🇵

Share this article

One thought on “Xcode 13 and Swift Localization

Comments are closed.