What’s the equivalent to String.localizedStringWithFormat(_:_:)
in SwiftUI?
I know LocalizedStringKey.init(:)
can make use of string interpolation, but as I understand it this requires localizable string keys to be parameterized in the .strings/.stringsdict files.
This is different to how localized string keys are currently defined in the app I'm working on. Given these localizable strings in Localizable.strings:
"HELLO_WORLD" = "Hello, world!";
"HELLO_WORLD_PARAMETERIZED" = "Hello, %@!";
this works just fine in the Foundation/UIKit world:
NSLocalizedString("HELLO_WORLD", comment: "") // "Hello, world!"
String.localizedStringWithFormat(NSLocalizedString("HELLO_WORLD_PARAMETERIZED", comment: ""), "Bob") // "Hello, Bob!"
But I don’t see how to make it work in SwiftUI:
let helloWorld = LocalizedStringKey("HELLO_WORLD")
Text(helloWorld) // ✅ Displays "Hello, world!"
Text("HELLO_WORLD") // ✅ Also displays "Hello, world!"
LocalizedStringKey("HELLO_WORLD_PARAMETERIZED", "Bob") // ❌ This won't compile, because LocalizedStringKey has no format parameter like `String.localizedStringWithFormat(_:_:)` does.
let bob = "Bob"
LocalizedStringKey("Hello, \(bob)!") // 🤔 This *would* work if the key in Localizable.strings were "Hello, %@!" – but this doesn't reflect the reality of localized string keys are currently defined for this app.
Text(verbatim: String.localizedStringWithFormat(NSLocalizedString("HELLO_WORLD_PARAMETERIZED", comment: ""), "Bob")) // 🙈 This correctly displays "Hello, Bob!" in the Text view, but... well, it ain't pretty.
Do I have to change all my localizable string keys (as opposed to just their values) to be parameterized in order to be able to use them in SwiftUI views (without using the Text(verbatim:)
workaround)?
The key used to look up an entry in a strings file or strings dictionary file.
Recent versions of XCode doesn't create Localizable. strings file by default. To add Localizable. strings file, go to File->New->File , choose Strings File under Resource tab of iOS, name it Localizable.
Select the project and under “Localizations”, click the “+” icon. Add any language you want (I selected Italian) then click on “Finish”. Now go back to Localizable. string file, select it and on the File Inspector (right menu) select “Localize”.
A localized string can have different values depending on the language in which the project is being build. There are two categories of localized strings: the strings included in the installation package's UI, common to every MSI file.
I faced this issue as well and thanks to some sources and links I think I got it working the expected way.
I was working on Xcode 12 Beta 6 when I succeeded, I can not confirm/infirm on other versions.
The translation key needs to reflect the interpolated string you'll use in SwiftUI in which every argument is replaced by the String Format specifier representing the type of the argument.
In your example, you want to insert one String
as parameter. This corresponds to the %@
specifier.
Rewrite your Localizable.strings
by:
"HELLO_WORLD" = "Hello, world!";
"HELLO_WORLD_PARAMETERIZED %@" = "Hello, %@!";
To use it inside a Text
:
Text("HELLO_WORLD_PARAMETERIZED \(someStringVar)")
If you want to use a UInt
parameter, use the %llu
identifier, %lld
for Int
(see the String Format specifier link)
The same rules apply for .stringdict
, name the key using the same pattern:
<dict>
<key>%llu elements</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@VARIABLE@</string>
<key>VARIABLE</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>llu</string>
<key>zero</key>
<string>No elements</string>
<key>one</key>
<string>One element</string>
<key>other</key>
<string>%llu elements</string>
</dict>
</dict>
</dict>
</plist>
To use the key:
Text("\(someUIntVarValue) elements")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With