A tiny bit i18n in SwiftUI / XCode 14
Tags: swift, beginners
Published: 2023-04-24 01:20:42

## Introduction
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.

I used to do some development using WinForms and WPF, too.

**Why is this relevant?**
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.

For reference: I am using XCode 14.3 and targeting MacOS 13, the rest is very much left at default.

## The problem: how to i18n a tiny and simple SwiftUI application easily?
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.

![Example of the configurator app in DE locale](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vr2p5bc7o5oy1vhrgo16.png)

I am slowly working through understanding it all.

However: **why is the internationalization of apps so complicated when developing using XCode and SwiftUI?**
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 `View` and the likes. I expected to have to create it all by myself.

## Solution (TL;DR: let XCode do it for you)
### Assumption
My main mistake was to follow most tutorials, that suggest to create `.strings` files and simply replace whatever is in `Text("...")` with the key.

For example, given the following excerpt (in a `View`):
```
...
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")
...
```

You'd think taking the text (first argument of `Text`) and assigning it to some key in your `.strings` file is the way to go, but while it may work, **it did not for me**.

### Let XCode do the work for you!
In reality it's simpler than this:
1. Make sure the following settings are activated under the project build settings:
  1. `Localization Export Supported`
  1. `Localized String SwiftUI Support`
  1. `Use Compiler to Extract Swift Strings`
1. *Side-note:* should you enable `Missing Localizability` or `Missing Localization Context Comment`, all your strings, that are missing localization, will most-likely be displayed as "all-caps".
1. Design your `View` structs etc. as you want (including `comment` attributes in your `Text` widgets can help further down the line).
1. Chose `Product` -> `Export Localizations...` in XCode.
1. Chose the path you want XCode to export your strings to (the folder will contain a couple `*.xcloc` files; these files could be sent to translators).
1. Edit the `*.xcloc` files as needed.

![XCode xcloc editor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zexi7uf7w8kig7vo4aio.png)
1. Chose `Product` -> `Import Localizations...` in XCode.
1. Check the changes if you can and want.
1. Click onto the "Import" button.

![XCode merge editor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c5gife22gg1gje3xjnb1.png)

**The first time** you do it, it will import the `Localizable.strings` and `<app>-InfoPlist.strings` files. The keys will be the full messages you used in your `Text` widgets, but now instead of simply displaying them, the application will translate them by mapping them using the given locale and the `.strings` files (or so it seems).

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

## Conclusion
XCode does a lot to help one with exporting and importing localization files and extracting strings from existing `View`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.

**Note:** I also encountered, that in the merge editor (before pressing the "Import" button) only changes to the `<app>-InfoPlist.strings` was displayed while the changes in `Localizable.strings` were not. However: when importing, both changes were applied.

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!