Localization of dynamic text received by web services

Hi,

my SwiftUI app is localized by using translation files (German, English).

In one of my views I have to present a text received by a webservice. The webservice provides the text in German and English.

What is the best practice to show the correct string?

First idea: Check the current locale, if it is German than show the German text, else show the English one. Is this the best way to implement this?

Second idea: Is there a possibility to use NSLocalizedString without a language file and to provide the translations programmatically? In this case I wouldn't have to check the locale on myself. therefore I would prefer this...

Thanks in advance!

Mark

  • Example for getting locale: let languagePrefix = Locale.preferredLanguages[0].prefix(2)

Add a Comment

Accepted Reply

Generally, the first idea is recommended; however, your example for getting the locale is a localization anti-pattern for a few reason:

  1. What if the user has a device running in Turkish, but prefers German over English? Then their Locale.preferredLanguages could look something like [tr, de, en]—so the first element would be neither English nor German.
  2. Language codes can sometimes be three characters (ex: chr), so doing .prefix(2) is not future-proof if your server supports additional languages
  3. Locale.preferredLanguages will return user's preferred languages, regardless of the languages your application bundle supports—so it's not useful for getting the current running application language. We need to consider the current running application language to inform what language to request content from your server, so users get a consistent experience.

The good news is that Bundle APIs handle these (and many other) complex edge cases for matching languages for you, so you can lean on this APIs and pass in the languages your server supports:

// Get the languages that the server supports. i.e. ["en", "de"]
let availableLanguages = Server.requestAvailableLanguages() 

// Returns the first language from `availableLanguages` considering the language the application is running in
let requestLanguage = Bundle.preferredLocalizations(from: availableLanguages).first

You can learn more about Bundle and Locale APIs in this WWDC talk: https://developer.apple.com/wwdc19/403?time=239

  • Thank you, your explanations and the video helped a lot, works for me!

Add a Comment

Replies

Generally, the first idea is recommended; however, your example for getting the locale is a localization anti-pattern for a few reason:

  1. What if the user has a device running in Turkish, but prefers German over English? Then their Locale.preferredLanguages could look something like [tr, de, en]—so the first element would be neither English nor German.
  2. Language codes can sometimes be three characters (ex: chr), so doing .prefix(2) is not future-proof if your server supports additional languages
  3. Locale.preferredLanguages will return user's preferred languages, regardless of the languages your application bundle supports—so it's not useful for getting the current running application language. We need to consider the current running application language to inform what language to request content from your server, so users get a consistent experience.

The good news is that Bundle APIs handle these (and many other) complex edge cases for matching languages for you, so you can lean on this APIs and pass in the languages your server supports:

// Get the languages that the server supports. i.e. ["en", "de"]
let availableLanguages = Server.requestAvailableLanguages() 

// Returns the first language from `availableLanguages` considering the language the application is running in
let requestLanguage = Bundle.preferredLocalizations(from: availableLanguages).first

You can learn more about Bundle and Locale APIs in this WWDC talk: https://developer.apple.com/wwdc19/403?time=239

  • Thank you, your explanations and the video helped a lot, works for me!

Add a Comment