Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI: Variable strings not exported for localization

As per Apple documentation, this should work:

If you initialize a text view with a string variable rather than a string literal, the view triggers the init(:) initializer instead, because it assumes that you don’t want localization in that case. If you do want to localize the value stored in a string variable, you can choose to call the init(:tableName:bundle:comment:) initializer by first creating a LocalizedStringKey instance from the string variable:

Text(LocalizedStringKey(someString)) // Localizes the contents of someString.

https://developer.apple.com/documentation/swiftui/text/init(_:tablename:bundle:comment:)

This is also recommended here: https://www.ibabbleon.com/swiftui_localization_tutorial.html

However, at least in my case, it does not. In the following example, only "Some content 1" value is exported for localization.

struct ContentView: View {
    let text = "Some content 2"
    var body: some View {
        Text("Some content 1", comment: "This text is exported for localization, as expected.")
            .padding()
        Text(LocalizedStringKey(text), comment: "This text is not exported for localization, which is not expected behaviour.")
            .padding()
    }
}

In the app settings, "Use compiler to extract swift strings" is set to Yes.

What am I missing?

like image 846
blu-Fox Avatar asked Oct 12 '25 09:10

blu-Fox


2 Answers

Ok, so after tinkering with localization some more, I found an approach that works well.

The tutorial I linked to (https://www.ibabbleon.com/swiftui_localization_tutorial.html) does not talk about this, and makes things confusing with LocalizedStringKey and Text(String, comment: String). Some other tutorials also go down this route, but it makes code really ugly because it moves data into Text. So if you want to separate data from the view, you have to include Text (a UI element) in the view model. Alternatively, if you use LocalizedStringKey, you can't include comments for the translator.

Fortunately, there is a much simpler way!

struct ContentView: View {
  let normalString = "This is not exported for localization. Good for previews!"
  let localizedString = String(localized: "This is exported for localization.", comment: "You can add a comment for the translator, too!")

  var body: some View {
    VStack {
      Text(normalString)
      Text(localizedString)
    }
  }
}
like image 109
blu-Fox Avatar answered Oct 16 '25 08:10

blu-Fox


You already found that doing let content2: LocalizedStringKey = "Some content 2" fixes your issue but still had a question about how to include a comment.

Apple noted in their Localize your SwiftUI App session at WWDC 21 that one approach is to have the argument to your view be of the type Text so that you can provide the comment.

struct ContentView: View {
    let text = Text("Some content 2", comment: "This gets exported!")
    var body: some View {
        Text("Some content 1", comment: "This text is exported for localization, as expected.")
            .padding()
        text
            .padding()
    }
}
like image 28
Helam Avatar answered Oct 16 '25 07:10

Helam



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!