Localizing Attributed Strings on iOS

Published Jul 17, 2017
Localizing Attributed Strings on iOS

Localization can be especially difficult when dealing with attributed strings in an iOS app. Fairly often, designers request something like:

Read our Terms of Service, Privacy Policy, or contact us with any questions.

or like:

Searching for burgers in SOMA, San Francisco, CA:

The golden rule of localized strings is to treat them as atomic units:

  • Never concatenate strings to form sentences. Many languages have different sentence structures or gender rules from English. You cannot just substitute a single word or phrase in for any other.
  • Never use substrings when searching in an original string. If you depend on the standalone translation of "Privacy Policy" matching the sentence version, you will likely find translators do not understand this intent. You may also find the same search term multiple times (imagine if the user searched for "Search").

Often these complexities are cited as reasons to avoid localization. But, unless you have geographic constraints, you will find a substantially larger audience with a localized application.

ZSWTappableLabel and ZSWTaggedString are two open-source libraries I have released to help solve these problems.

As the name suggests, ZSWTappableLabel makes the links inside your attributed strings tappable. It's a fast and easy UILabel subclass as it does not do any drawing itself.

ZSWTaggedString is the powerhouse. It transforms an HTML-like syntax into an attributed string. You can read more about the syntax and the advanced usage on its GitHub page, but here's how you might use it for the examples mentioned above:

Read our <i><tos>Terms of Service</tos></i>, <i><privacy>Privacy Policy</privacy></i>, or <i><contact>contact us</contact></i> with any questions.

Searching for <term>%@</term> in <location>%@</location>:

In my experience, localizers are familiar enough with HTML that they won’thave issues with localizing these strings. By marking the regions you intend to be visually distinct, they can easily understand your intent and produce better localizations.

While on the subject, here are a few best practices for localization in iOS:

  • Reload your UI when observing to handle the current locale or dynamic type setting changing:
    • NSCurrentLocaleDidChangeNotification
    • UIContentSizeCategoryDidChangeNotification
  • To represent dates, durations, distances, lengths, etc., use an appropriate formatter.
  • To create your own date formats, use +dateFormatFromTemplate:options:locale: on NSDateFormatter. Remember that this needs to be recreated if the locale changes.
  • To combine a first and last name, use ABPersonGetCompositeNameFormatForRecord with a temporary ABPersonRef, or use the new NSPersonNameComponentsFormatter.
  • For sending non-user-facing data to a server, use en_US_POSIX as your locale.

Read more tips and tricks at NSHipster on NSLocalizedString and NSLocale.

(This is from my blog.)

Discover and read more posts from Zachary West
get started