Reputation: 605
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
.
Upvotes: 3
Views: 857
Reputation: 14968
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:
public extension LocalizedStringKey {
init(_ value: String, comment: String) {
self.init(value)
}
}
and always used that, you'd be able to use LocalizedStringKey
by passing -s LocalizedStringKey
to genstrings
.
Keep in mind that if you declared LocalizedStringKey
as a return type or a variable, that would give a genstrings
error, too. So you'd need a separate typealias LocalizedStringKeyResult = LocalizedStringKey
that you use when reference LocalizedStringKey
but don't want genstrings
to complain.
And, of course, you wouldn't get the interpolation you want because genstrings
applies that only to Text
.
The real answer is... don't use LocalizedStringKey
. Use Text
when you can (to get interpolation). Use NSLocalizedString
when you can't.
Upvotes: 3