{"id":116521,"date":"2020-04-30T19:35:23","date_gmt":"2020-04-30T19:35:23","guid":{"rendered":"https:\/\/developer.apple.com\/news\/?id=u2cfuj88"},"modified":"2020-04-30T19:35:23","modified_gmt":"2020-04-30T19:35:23","slug":"how-to-support-per-app-language-settings-in-your-app","status":"publish","type":"post","link":"https:\/\/sickgaming.net\/blog\/2020\/04\/30\/how-to-support-per-app-language-settings-in-your-app\/","title":{"rendered":"How to support per-app language settings in your app"},"content":{"rendered":"<div class=\"inline-article-image\"><img decoding=\"async\" src=\"https:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2020\/08\/how-to-support-per-app-language-settings-in-your-app.jpg\" data-hires=\"false\"><\/div>\n<p>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\u2019s language to English, but want to use a social media app in Arabic.<\/p>\n<p>Good news: If your project is built with iOS 13 or macOS Catalina and localized into more than one language, you won\u2019t have to add any additional code to your app. Simply build and deploy your app to test.<\/p>\n<p>Here\u2019s how someone might check per-app language switching for a specific app, using AllTrails as an example.<\/p>\n<ol>\n<li><strong>Open<\/strong> the Settings app.<\/li>\n<li>Navigate to <strong>AllTrails &gt; Preferred Language &gt; Language<\/strong>.<\/li>\n<li>Change the preferred language to <strong>Spanish<\/strong>.<\/li>\n<li>Launch <strong>AllTrails<\/strong> from your home screen (or from the App Switcher, if the app is already open).<\/li>\n<\/ol>\n<div class=\"inline-article-image\" readability=\"34\"><img decoding=\"async\" src=\"https:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2020\/08\/how-to-support-per-app-language-settings-in-your-app-1.jpg\" data-hires=\"false\"><\/p>\n<p class=\"typography-caption\">Once someone has set their preferred languages for an app in Settings, it will then render accordingly in your app.<\/p>\n<\/div>\n<p>AllTrails will now render in Spanish, while the rest of the device continues to display the system language.<\/p>\n<h3>Restore your state after a change in the language setting<\/h3>\n<p>If someone decides mid-activity that they\u2019d 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\u2019re living abroad and looking for food using a restaurant delivery app. By default, you use English, but might want to switch the app\u2019s language when viewing a certain restaurant\u2019s menu so that you can better understand its native dishes.<\/p>\n<p>If that app supports state restoration, you can exit to the Settings app and return to the restaurant you were viewing \u2014 now in the new language. If not, you\u2019ll have to start from the app\u2019s main screen and find that restaurant again.<\/p>\n<p>If your app supports scene-based state restoration, you can implement <code>stateRestorationActivity(for scene)<\/code> and return an <code>NSUserActivity<\/code> that encodes the scene state. (And if you still support view controller state restoration, you can enable state restoration on your app delegate.)<\/p>\n<hr>\n<p><a href=\"http:\/\/developer.apple.com\/news\/?id=4ixc0yxs\">Learn more about implementing state restoration &gt;<\/a><\/p>\n<hr>\n<h3>How to load custom content in the correct language<\/h3>\n<p>If you need to load content from other sources, such as a server, you can do so and ensure that you match the app\u2019s language with a few bundle APIs.<\/p>\n<p><code>Bundle.main.preferredLocalizations.first<\/code> will get the system\u2019s current language in priority order.<\/p>\n<p>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:<\/p>\n<pre class=\"code-source\"><code><span class=\"syntax-keyword\">let<\/span> availableLanguages = <span class=\"syntax-type\">Server<\/span>.requestAvailableLanguages()<\/code><\/pre>\n<p>Then, use the <code>preferredLocalization<\/code> API with those languages:<\/p>\n<pre class=\"code-source\"><code><span class=\"syntax-type\">Bundle<\/span>.preferredLocalizations(from: availableLanguages).first.<\/code><\/pre>\n<p>If it\u2019s not possible to have ongoing communication with the server due to connectivity or other constraints, you can also send the output of <code>Bundle.main.preferredLocalizations.first<\/code> to the server; that way, it will know which language the app has been launched in and deliver content accordingly.<\/p>\n<h3>How to transition away from a custom language selector in your app<\/h3>\n<p>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.<\/p>\n<p>If you\u2019d like to guide people to the system settings for language selection, you can replace your app\u2019s custom UI with a flow that launches directly into the Settings app on iOS.<\/p>\n<p>On iOS, add the following: <\/p>\n<pre class=\"code-source\"><code><span class=\"syntax-type\">UIApplication<\/span>.shared.<span class=\"syntax-keyword\">open<\/span>(<span class=\"syntax-type\">URL<\/span>(string: <span class=\"syntax-type\">UIApplication<\/span>.openSettingsURLString)!)<\/code><\/pre>\n<p>On macOS, direct people to <strong>System Preferences &gt; Language &amp; Region<\/strong> to add a per-language setting for your app.<\/p>\n<hr>\n<h3>Resources<\/h3>\n<p><a href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2019\/403\">Watch \u201cCreating Great Localized Experiences with Xcode 11\u201d &gt;<\/a><\/p>\n<p><a href=\"https:\/\/developer.apple.com\/localization\/?cid=developer80\">Learn more about expanding your app to new markets &gt;<\/a><\/p>\n<p><a href=\"https:\/\/developer.apple.com\/localization\/resources\/?cid=developer80\">Get more resources for localization &gt;<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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\u2019s language to English, but [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":116522,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[55],"tags":[],"class_list":["post-116521","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-apple-developer-news"],"_links":{"self":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/116521","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/comments?post=116521"}],"version-history":[{"count":0,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/116521\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media\/116522"}],"wp:attachment":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media?parent=116521"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/categories?post=116521"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/tags?post=116521"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}