How to support per-app language settings in your app
April 30, 2020
When you localize your app, people all over the world can view your content in the language they feel most comfortable reading. And with the latest versions of iOS and macOS, people can have even more control by choosing languages on a per-app basis. For example, someone may set their iPhone’s language to English, but want to use a social media app in Arabic.
Good news: If your project is built with iOS 13 or macOS Catalina and localized into more than one language, you won’t have to add any additional code to your app. Simply build and deploy your app to test.
Here’s how someone might check per-app language switching for a specific app, using AllTrails as an example.
- Open the Settings app.
- Navigate to AllTrails > Preferred Language > Language.
- Change the preferred language to Spanish.
- Launch AllTrails from your home screen (or from the App Switcher, if the app is already open).
AllTrails will now render in Spanish, while the rest of the device continues to display the system language.
Restore your state after a change in the language setting
If someone decides mid-activity that they’d like to view your app in a different language, you can make the experience even smoother for them by restoring their previous state when they return. For example, say you’re living abroad and looking for food using a restaurant delivery app. By default, you use English, but might want to switch the app’s language when viewing a certain restaurant’s menu so that you can better understand its native dishes.
If that app supports state restoration, you can exit to the Settings app and return to the restaurant you were viewing — now in the new language. If not, you’ll have to start from the app’s main screen and find that restaurant again.
If your app supports scene-based state restoration, you can implement
stateRestorationActivity(for scene) and return an
NSUserActivity that encodes the scene state. (And if you still support view controller state restoration, you can enable state restoration on your app delegate.)
How to load custom content in the correct language
If you need to load content from other sources, such as a server, you can do so and ensure that you match the app’s language with a few bundle APIs.
Bundle.main.preferredLocalizations.first will get the system’s current language in priority order.
If you need to check against a custom set of available languages (say, from a server or other source), you can do so with a simple modification to the previous API call. First, find out what available languages there are:
let availableLanguages = Server.requestAvailableLanguages()
Then, use the
preferredLocalization API with those languages:
If it’s not possible to have ongoing communication with the server due to connectivity or other constraints, you can also send the output of
Bundle.main.preferredLocalizations.first to the server; that way, it will know which language the app has been launched in and deliver content accordingly.
How to transition away from a custom language selector in your app
With systemwide support for in-app language selectors, you no longer need to provide a way to select languages within your app if you support iOS 13 or macOS Catalina or later. If you currently offer such a UI, you should remove it to avoid customer confusion and potential conflict with the system.
If you’d like to guide people to the system settings for language selection, you can replace your app’s custom UI with a flow that launches directly into the Settings app on iOS.
On iOS, add the following:
On macOS, direct people to System Preferences > Language & Region to add a per-language setting for your app.