<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: divStar</title>
    <description>The latest articles on Forem by divStar (@divstar).</description>
    <link>https://forem.com/divstar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F795125%2F4e59dfb4-9246-4349-8480-e7ebc2ab3958.png</url>
      <title>Forem: divStar</title>
      <link>https://forem.com/divstar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/divstar"/>
    <language>en</language>
    <item>
      <title>A tiny bit i18n in SwiftUI / XCode 14</title>
      <dc:creator>divStar</dc:creator>
      <pubDate>Mon, 24 Apr 2023 01:20:42 +0000</pubDate>
      <link>https://forem.com/divstar/a-tiny-bit-i18n-in-swiftui-xcode-14-1jn0</link>
      <guid>https://forem.com/divstar/a-tiny-bit-i18n-in-swiftui-xcode-14-1jn0</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I am very new to SwiftUI and XCode and only a regular Mac user for 1,5 years. I mostly develop Java server software (and do so for over 12 years now) and somewhat develop for the web.&lt;/p&gt;

&lt;p&gt;I used to do some development using WinForms and WPF, too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is this relevant?&lt;/strong&gt;&lt;br&gt;
What surprises me, might not surprise seasoned developers of Apple software. Also bear in mind, that in SwiftUI I am a newbie and therefore whatever worked for me, might not work for you.&lt;/p&gt;

&lt;p&gt;For reference: I am using XCode 14.3 and targeting MacOS 13, the rest is very much left at default.&lt;/p&gt;
&lt;h2&gt;
  
  
  The problem: how to i18n a tiny and simple SwiftUI application easily?
&lt;/h2&gt;

&lt;p&gt;I am developing a small configurator-type application in my spare-time, that will probably load and save a configuration file and that's it. Since it's currently supposed to be MacOS-only (for the time being), I decided to give XCode + SwiftUI a chance instead of writing it in golang, Java or anything else.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--etI7pigE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vr2p5bc7o5oy1vhrgo16.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--etI7pigE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vr2p5bc7o5oy1vhrgo16.png" alt="Example of the configurator app in DE locale" width="800" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am slowly working through understanding it all.&lt;/p&gt;

&lt;p&gt;However: &lt;strong&gt;why is the internationalization of apps so complicated when developing using XCode and SwiftUI?&lt;/strong&gt;&lt;br&gt;
It felt so complicated, because I was actually expecting to have to create dictionary files, fill them, make sure to connect them somehow to a &lt;code&gt;View&lt;/code&gt; and the likes. I expected to have to create it all by myself.&lt;/p&gt;
&lt;h2&gt;
  
  
  Solution (TL;DR: let XCode do it for you)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Assumption
&lt;/h3&gt;

&lt;p&gt;My main mistake was to follow most tutorials, that suggest to create &lt;code&gt;.strings&lt;/code&gt; files and simply replace whatever is in &lt;code&gt;Text("...")&lt;/code&gt; with the key.&lt;/p&gt;

&lt;p&gt;For example, given the following excerpt (in a &lt;code&gt;View&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
Text("Click on individual areas in the device picture to configure them",
                         comment: "Instructs the user to click on individual areas of the device picture shown in order to configure the associated controls")
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'd think taking the text (first argument of &lt;code&gt;Text&lt;/code&gt;) and assigning it to some key in your &lt;code&gt;.strings&lt;/code&gt; file is the way to go, but while it may work, &lt;strong&gt;it did not for me&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let XCode do the work for you!
&lt;/h3&gt;

&lt;p&gt;In reality it's simpler than this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make sure the following settings are activated under the project build settings:

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Localization Export Supported&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Localized String SwiftUI Support&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Use Compiler to Extract Swift Strings&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Side-note:&lt;/em&gt; should you enable &lt;code&gt;Missing Localizability&lt;/code&gt; or &lt;code&gt;Missing Localization Context Comment&lt;/code&gt;, all your strings, that are missing localization, will most-likely be displayed as "all-caps".&lt;/li&gt;
&lt;li&gt;Design your &lt;code&gt;View&lt;/code&gt; structs etc. as you want (including &lt;code&gt;comment&lt;/code&gt; attributes in your &lt;code&gt;Text&lt;/code&gt; widgets can help further down the line).&lt;/li&gt;
&lt;li&gt;Chose &lt;code&gt;Product&lt;/code&gt; -&amp;gt; &lt;code&gt;Export Localizations...&lt;/code&gt; in XCode.&lt;/li&gt;
&lt;li&gt;Chose the path you want XCode to export your strings to (the folder will contain a couple &lt;code&gt;&lt;em&gt;.xcloc&lt;/em&gt;&lt;/code&gt; files; these files could be sent to translators).&lt;/li&gt;
&lt;li&gt;Edit the &lt;code&gt;.xcloc&lt;/code&gt; files as needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ufhQWXKs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zexi7uf7w8kig7vo4aio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ufhQWXKs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zexi7uf7w8kig7vo4aio.png" alt="XCode xcloc editor" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Chose &lt;code&gt;Product&lt;/code&gt; -&amp;gt; &lt;code&gt;Import Localizations...&lt;/code&gt; in XCode.&lt;/li&gt;
&lt;li&gt;Check the changes if you can and want.&lt;/li&gt;
&lt;li&gt;Click onto the "Import" button.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CE4uU4Lm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c5gife22gg1gje3xjnb1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CE4uU4Lm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c5gife22gg1gje3xjnb1.png" alt="XCode merge editor" width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The first time&lt;/strong&gt; you do it, it will import the &lt;code&gt;Localizable.strings&lt;/code&gt; and &lt;code&gt;&amp;lt;app&amp;gt;-InfoPlist.strings&lt;/code&gt; files. The keys will be the full messages you used in your &lt;code&gt;Text&lt;/code&gt; widgets, but now instead of simply displaying them, the application will translate them by mapping them using the given locale and the &lt;code&gt;.strings&lt;/code&gt; files (or so it seems).&lt;/p&gt;

&lt;p&gt;To test your application in a given language, go to &lt;code&gt;Product&lt;/code&gt; -&amp;gt; &lt;code&gt;Scheme&lt;/code&gt; -&amp;gt; &lt;code&gt;Edit Scheme...&lt;/code&gt; and go into the &lt;code&gt;Options&lt;/code&gt; tab of your &lt;code&gt;Run/Debug&lt;/code&gt; configuration. There select the desired &lt;code&gt;App Language&lt;/code&gt; or use &lt;code&gt;System Language&lt;/code&gt; if you prefer that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;XCode does a lot to help one with exporting and importing localization files and extracting strings from existing &lt;code&gt;View&lt;/code&gt;s, but I feel like either I was unlucky and was not able to find this in the documentation - or I did not understand it. In fact it is very straight forward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I also encountered, that in the merge editor (before pressing the "Import" button) only changes to the &lt;code&gt;&amp;lt;app&amp;gt;-InfoPlist.strings&lt;/code&gt; was displayed while the changes in &lt;code&gt;Localizable.strings&lt;/code&gt; were not. However: when importing, both changes were applied.&lt;/p&gt;

&lt;p&gt;This is one of a few articles I wrote in years, so I apologize for its quality. I just wanted to quickly share this knowledge with others as it took me about 1-2 hours to figure out how all this works. Because I am a newbie in XCode and SwiftUI, I am not sure, that I can help with any issues you may have; however: if you know how to improve this article, especially if there are mistakes, please drop me a comment so I can fix it. Cheers!&lt;/p&gt;

</description>
      <category>swift</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
