Search code examples
iosswiftswiftui

How to properly build localization string key with a variables inside of it


I have the following code:

Text("key.\(item.count) \(item.actionName)")

And based on item.actionName, I need to provide different translations to implement pluralization correctly. item.count is of type Double (it have step of 0.5) and item.actionName is of type String.

I thought that using different keys in the catalog, like this:

"key.%f actionName1", "key.%f actionName2"

would work. Additionally, the translation would be just "%f actionName" without the .key part, which I used for kind of "namespacing" among other keys.

However, this approach doesn't seem to work as expected. Xcode seems to interpret(I guess?) the string from the Text view as:

"key.%f %@"

rather than "key.%f actionName1". How can I implement this properly?

Also, I'm aware of the ^[\(item.count) actionName"](inflect: true) approach. However, it seems to work mostly with English, so that's not an option for me.

I tried to use String(localized:) but probably wrongly, so...

Any suggestions would be greatly appreciated!


Solution

  • A hack you could use is to add a new overload of appendInterpolation that appends a string as a literal.

    extension LocalizedStringKey.StringInterpolation {
        mutating func appendInterpolation(literal: String) {
            appendLiteral(literal)
        }
    }
    

    Then you can do:

    let actionName = "foo"
    var body: some View {
        Text("\(1.0, specifier: "%.1f") \(literal: actionName)")
        Text("\(2.0, specifier: "%.1f") \(literal: actionName)")
    }
    

    Finally, add keys like this to your string catalog.

    enter image description here

    Localisation keys will not be automatically generated in the string catalog when you build the project.

    See also: Choosing Plural Category Names