How does the app pick its language at runtime, and how is that different from Locale?
Predict first
What does this print?
print(Bundle.preferredLocalizations(from: ["en", "fr", "de"], forPreferences: ["fr-CA", "en"]))
- ["fr"]
- ["en"]
- ["fr-CA"]
Mental model. Language is which book you read. Locale is the conventions for how numbers and dates are written inside any book.
The system keeps an ordered list of the user’s preferred languages. At launch, Bundle matches that list against the localisations your app actually ships (its .lproj folders), picks the first match, and falls back to the development language. Bundle.preferredLocalizations(from:forPreferences:) exposes that logic. The result is fixed for the process, so a language change takes effect on the next launch. Users can also set a language for a single app in Settings.
That is the language. Locale (region formats) is separate: it decides number, date and currency formats, and can differ from the language. Test with the scheme’s Application Language and App Region, with pseudolanguages (double-length, right-to-left, accented), or the launch argument -AppleLanguages (fr).
The user prefers Canadian French first. The app ships plain fr, which is the closest match, so it wins over English.
Common traps
- Assuming an unsupported language falls back to English. It falls back to your development language, which is whatever you set.
- Forgetting to add the localisation. A
.stringsfile without the project localisation is never matched.
They might follow up with
- How do you read the current choice?
Bundle.main.preferredLocalizations.first. - Can an app switch language live? Not through the system bundle lookup; the supported path is the per-app language setting.
Related questions
- 2.6.3 How do you localise strings: Localizable.strings, string catalogs, String(localized:)?
- 2.2.6 What is a Locale, and how is it different from the user’s language?
← How do you handle plurals and word order in localised strings?