New in iOS 15, we are invited to use this String initializer method to make localizable strings in our Swift code:
init(localized keyAndValue: String.LocalizationValue,
table: String? = nil, bundle: Bundle? = nil,
locale: Locale = .current, comment: StaticString? = nil)
The trouble is that the first parameter is, as the internal name suggests, used for both the key and the value. You can see that from this localized French strings file:
/* Alert message: Report a tap */
"You tapped me!" = "Vous m'avez tapé!";
That resulted from my saying
String(localized:"You tapped me!", comment: "Alert message: Report a tap")
and localizing for French.
That's totally wrong! This is supposed to be a list of key–value pairs; we shouldn't be using the English user-facing text as a key.
For one thing, if we now change the English text in our String(localized:comment:)
call, our French translation will break. Also, we would be unable to have different French translations for the same English text used in different contexts.
What are we supposed to do about this?
I regard this as a major bug in String(localizable:)
. If we were using NSLocalizedString, we would have individual key:
and value:
parameters. String(localizable:)
needs that.
I can think of two workarounds. One is: don't use String(localizable:)
. Just keep on using NSLocalizedString.
The other is to localize explicitly for English. Instead of entering the English user-facing text as the localized:
parameter, enter a key string. Then, to prevent the keys from appearing in the user interface, export the English localization and "translate" the keys into the desired English user-facing text. Now import the localization to generate the correct English .strings files.
(If your development language isn't English, substitute the development language into those instructions.)
Now when you export a different localization, such as French, the <trans-unit>
element's id
value is the key, to which the translator pays no attention, and the <source>
is the English, which the translator duly translates.
To change the English user-facing text later on, edit the English Localizable.strings file — not the code. Nothing will break because the key remains constant.