Is there a way get Apple's genstrings command line tool to recognize localizable string keys defined from SwiftUI's LocalizedStringKey initializer?
For this input file (testing-genstrings.swift): ...
import UIKit
import SwiftUI
enum L10n {
static let test0 = NSLocalizedString("TEST0", comment: "")
static let test1 = LocalizedStringKey("TEST1")
static func test2(_ parameter: String) -> LocalizedStringKey {
return LocalizedStringKey("TEST2_\(parameter)")
}
static func test3(_ parameter: String) -> String {
return NSLocalizedString("TEST3_\(parameter)", comment: "")
}
static func test4(_ parameter: String) -> String {
return String.localizedStringWithFormat(NSLocalizedString("TEST4", comment: ""), parameter)
}
}
let test5 = "TEST5"
let test6 = "TEST6"
let test7 = "TEST7"
struct TestView: View {
var body: some View {
VStack {
Text(L10n.test0)
Text(L10n.test1)
Text(L10n.test2("foo"))
Text(L10n.test3("bar"))
Text(test5)
Text(LocalizedStringKey(test6))
Text(NSLocalizedString(test7, ""))
Text("TEST8")
Text("TEST9_\("baz")")
}
}
}
...genstrings generates this output:
$ genstrings -SwiftUI -s LocalizedStringKey testing-genstrings.swift && iconv -c -f utf-16 -t utf-8 Localizable.strings
genstrings: error: bad entry in file testing-genstrings.swift (line = 9): Argument is not a literal string.
genstrings: error: bad entry in file testing-genstrings.swift (line = 11): Argument is not a literal string.
genstrings: error: bad entry in file testing-genstrings.swift (line = 12): Argument is not a literal string.
genstrings: error: bad entry in file testing-genstrings.swift (line = 36): Argument is not a literal string.
genstrings: error: bad entry in file testing-genstrings.swift (line = 37): Argument is not a literal string.
genstrings: error: bad entry in file testing-genstrings.swift (line = 37): Argument is not a literal string.
/* No comment provided by engineer. */
"bar" = "bar";
/* No comment provided by engineer. */
"foo" = "foo";
/* No comment provided by engineer. */
"TEST0" = "TEST0";
/* No comment provided by engineer. */
"TEST3_\(parameter)" = "TEST3_\(parameter)";
/* No comment provided by engineer. */
"TEST4" = "TEST4";
/* No comment provided by engineer. */
"TEST8" = "TEST8";
/* No comment provided by engineer. */
"TEST9_%@" = "TEST9_%@";
You can see that it recognizes the keys defined via NSLocalizedString and Text's initializer Text() initializer that uses ExpressibleByStringInterpolation (TEST9_%@ in the example), but fails on all keys defined using LocalizedStringKey.
genstringsis relatively naive. It is looking for a function with two parameters, the first unnamed, the second named "comment".If you added the following extension:
and always used that, you'd be able to use
LocalizedStringKeyby passing-s LocalizedStringKeytogenstrings.Keep in mind that if you declared
LocalizedStringKeyas a return type or a variable, that would give agenstringserror, too. So you'd need a separatetypealias LocalizedStringKeyResult = LocalizedStringKeythat you use when referenceLocalizedStringKeybut don't wantgenstringsto complain.And, of course, you wouldn't get the interpolation you want because
genstringsapplies that only toText.The real answer is... don't use
LocalizedStringKey. UseTextwhen you can (to get interpolation). UseNSLocalizedStringwhen you can't.