New iOS String Initializer can't get correct localized String for specific locale

I tried to build LocalizedKeyString using String's new Initializer.

String(localized: "hello",locale: locale)

When I change the language setting of the device, everything works as expected.

However, when I try to get the string in a specific language using the specified Locale, I can only ever get the string in .current.

String(localized: "hello",locale: Locale(identifier: "zh-cn"))

    func getString(locale:Locale) -> String{

         String(localized: "hello",locale: locale)

    }

If you change the display language of the project (or the language setting of the device), the text in Text is always displayed correctly. Text(getString(locale:.current)) However, the code in onAppear print(getString(locale:Locale(identifier: "zh-cn"))) It only displays the same content as Text, but not the specified Chinese.

Is it my fault that the new Initializer The understanding is not correct, or the bug of String

init(localized keyAndValue: String.LocalizationValue, table: String? = nil, bundle: Bundle? = nil, locale: Locale = .current, comment: StaticString? = nil)

FB number: FB9675845

  • Thanks a lot for filing a feedback and attaching a demo project! Your feedback has been relayed

Add a Comment

Accepted Reply

Hi,

The locale parameter of String(localized:locale:) helps specifying a locale for interpolated values in the string.

For instance, this would display a date in the English (UK) format:

String(localized: "Next Meeting: \(date, format: Date.FormatStyle(date: .numeric))", locale: Locale(identifier: "en_GB"))
// Localizable string is:    Next Meeting: %@
// Returns:                  Next Meeting: 25/12/2020

 

Any reason why you'd need to load strings in a specific locale instead of the current user’s locale? Users can change their device language, but also for each app.

  • Thanks for your reply, it helped me to figure out the use of locale, it seems I had a problem understanding locale in String before. I used the new Formatter API ParseableFormatStyle and tried to let it be used to specify the text in the output by the following code

    let colorString = UIColorFormatStyle().mark().locale(Locale(identifier: "zh-cn")).format(UIColor.blue)

    Looks like I need to tweak the string handling a bit.

    https://www.fatbobman.com/posts/newFormatter/

  • Where is the documentation for String(localized:? One month after iOS 15 has been released, the official documentation still declares No overview available and treats it as beta.

Add a Comment

Replies

You could try to specify the Bundle:

extension String {
    func localized(for lanCode: String) -> String {
        guard
            let bundlePath = Bundle.main.path(forResource: lanCode, ofType: "lproj"),
            let bundle = Bundle(path: bundlePath)
        else { return "" }
        
        return NSLocalizedString(
            self,
            bundle: bundle,
            value: " ",
            comment: ""
        )
    }
}

And call:

"hello".localized(for: "cn")

CRedit: https://stackoverflow.com/questions/28634428/ios-get-localized-version-of-a-string-for-a-specific-language

  • I wouldn’t recommend wrapping String(localized:) calls because it removes comments for translators (super useful to get the context like (to) Book vs (a) Book), and Xcode › Products › Export Localizations wouldn’t be able to add all declared strings automatically to .strings files for you.

Add a Comment

Hi,

The locale parameter of String(localized:locale:) helps specifying a locale for interpolated values in the string.

For instance, this would display a date in the English (UK) format:

String(localized: "Next Meeting: \(date, format: Date.FormatStyle(date: .numeric))", locale: Locale(identifier: "en_GB"))
// Localizable string is:    Next Meeting: %@
// Returns:                  Next Meeting: 25/12/2020

 

Any reason why you'd need to load strings in a specific locale instead of the current user’s locale? Users can change their device language, but also for each app.

  • Thanks for your reply, it helped me to figure out the use of locale, it seems I had a problem understanding locale in String before. I used the new Formatter API ParseableFormatStyle and tried to let it be used to specify the text in the output by the following code

    let colorString = UIColorFormatStyle().mark().locale(Locale(identifier: "zh-cn")).format(UIColor.blue)

    Looks like I need to tweak the string handling a bit.

    https://www.fatbobman.com/posts/newFormatter/

  • Where is the documentation for String(localized:? One month after iOS 15 has been released, the official documentation still declares No overview available and treats it as beta.

Add a Comment

treats it as beta.

You’re seeing the beta tag because this API is also new in macOS 12 and that system is still in the process of being released; it’ll go away when that’s fully complete.

still declares No overview available

Indeed. I encourage you to file a bug about that.

Please post your bug number, just for the record.

Do you have a question about its behaviour? It seems pretty straightforward to me but perhaps I’ve missed some subtlety?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • After the previous explanation, I have no more questions about the current behavior of this method. locale is used here to interpolate values for strings as a guide.

    Since I've been hoping Apple would provide an API to get the localizedString for a specific locale, for now I can only try to get it via Bundle directly.

Add a Comment