swiftswiftui

How to get string value from LocalizedStringKey?


I'm localizing my SwiftUI app with using LocalisedStringKey and the help of the following code:

Text(l10n.helloWorld)

Where l10n is:

enum l10n {
   internal static let helloWorld = LocalizedStringKey("hello.world")
}

Where "hello.world" is defined in the file Localizable.strings:

"hello.world" = "Hello world !";

While this code works in SwiftUI's View like this:

...
Text(i18n.helloWorld)
...

I can't find a way to get l10n value from LocalizedStringKey in code behind like this:

l10n.helloWorld.toString()

Solution

  • I think it's because SwiftUI is not mean't to do localization from code behind, all localization must happen in view declaration.

    However there's a way to achieve that via extensions methods :

    extension LocalizedStringKey {
    
        /**
         Return localized value of thisLocalizedStringKey
         */
        public func toString(arguments: CVarArg...) -> String {
            //use reflection
            let mirror = Mirror(reflecting: self)
            
            //try to find 'key' attribute value
            let attributeLabelAndValue = mirror.children.first { (arg0) -> Bool in
                let (label, _) = arg0
                if(label == "key"){
                    return true;
                }
                return false;
            }
            
            if(attributeLabelAndValue != nil) {
                //ask for localization of found key via NSLocalizedString
                return String.localizedStringWithFormat(NSLocalizedString(attributeLabelAndValue!.value as! String, comment: ""), arguments);
            }
            else {
                return "Swift LocalizedStringKey signature must have changed. @see Apple documentation."
            }
        }
    }
    

    Sadly you must use Reflection to achieve that as key has an internal level of protection in LocalizedStringKey, use at your own risks.

    Use asis :

    let s = l10n.helloWorld.toString();