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
.
genstrings
is 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
LocalizedStringKey
by passing-s LocalizedStringKey
togenstrings
.Keep in mind that if you declared
LocalizedStringKey
as a return type or a variable, that would give agenstrings
error, too. So you'd need a separatetypealias LocalizedStringKeyResult = LocalizedStringKey
that you use when referenceLocalizedStringKey
but don't wantgenstrings
to complain.And, of course, you wouldn't get the interpolation you want because
genstrings
applies that only toText
.The real answer is... don't use
LocalizedStringKey
. UseText
when you can (to get interpolation). UseNSLocalizedString
when you can't.