Reputation: 468
I am trying to localize my SwiftUI Watch app. I don't have any problems with static strings. I use LocalizedKeyStrings in my Text views and add my translations in Localizable.strings files. For example:
Text("history")
in Localizable.strings:
"history" = "Historique";
Result : "Historique"
But I also want to localize stings using interpolation. For example:
Text("startCustom \(format: "%.1f",customDistance)")
In Localizable.strings, I have tried with different syntax:
"startCustom %@" = "Course de %@ km";
or
"startCustom %f" = "Course de %f km";
or
"startCustom %.1f" = "Course de %.1f km";
Nothing works. I don't find any documentation for that ...
Upvotes: 22
Views: 17090
Reputation: 4987
Apparently, a LocalizedStringKey
will automatically generate the localization key depending on the type of the values interpolated. For example, if you have the following Text
s
Text("title key")
Text("name key \("Club")")
Text("count key \(8)")
Text("price key \(6.25)")
Your Localizable.strings file should look like
"title key" = "Sandwiches";
"name key %@" = "Name: %@";
"count key %lld" = "%lld sandwiches";
// You can change the format specifier in the value, but not in the key.
"price key %lf" = "Price: %.2lf";
Be careful if you want to support 32-bit systems (iPhone 5 or earlier). In a 32-bit system, Int
is Int32
, the key of "int32 key \(Int32(8))"
is "int32 key %d"
. You can always convert an integer to Int64
like in "count key \(Int64(8))"
to enforce consistent keys across different systems.
Remark 1: For people who want to know how it works. When you use a string literal or an interpolated string such as "count key \(8)"
in Text
, the compiler will consider the string as a LocalizedStringKey
, because Text
has an initializer
init(_ key: LocalizedStringKey, tableName: String? = nil, bundle: Bundle? = nil, comment: StaticString? = nil),
and LocalizedStringKey
conforms to ExpressibleByStringLiteral
and ExpressibleByStringInterpolation
and thus can be implicitly initialized from a string literal or a string interpolation.
Remark 2: If you're not sure what the key is, you can get the answer yourself by po a LocalizedStringKey in the debugger like this:
po LocalizedStringKey("count key \(8)")
Be sure to enable the build setting "Use Compiler to Extract Swift Strings" in your target. This way, when you use other Xcode tools like exporting localizations or the new String catalogs, the compiler can choose the correct format specifiers according to the interpolated value types. It can also identify your localized strings when you use the new String(localized:)
Swift API.
Upvotes: 38
Reputation: 257729
The following simple just works (tested with Xcode 11.4)
Text(String(format: NSLocalizedString("startCustom %.1f", comment: ""),
self.customDistance))
with Localizable.string having
"startCustom %.1f" = "Course de %.1f km";
Upvotes: 15
Reputation: 322
My way
Localizable file
"myNameIs %@" = "My name is %@.";
SwiftUI file
struct TestLocalize: View {
var name = "Hien Nguyen"
var body: some View {
Text("myNameIs \(name)")
}
}
Result
My name is Hien Nguyen
Upvotes: 7