-
Notifications
You must be signed in to change notification settings - Fork 766
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
R.swift not work well with automatic grammar agreement (^[..](inflect: true)
)
#858
Comments
Rswift works with .stringsdict files from Xcode, see: https://developer.apple.com/documentation/xcode/localizing-strings-that-contain-plurals Alternatively, as of Xcode 15, you can use a strings catalog: https://developer.apple.com/documentation/xcode/localizing-and-varying-text-with-a-string-catalog I suggest you first try to make your required behaviour work without Rswift, using the features from the platform, before adding Rswift code generation. |
Thanks for the advice @tomlokhorst! To make use of automatic grammar agreement, I will retrieve the localizable string without relying on R.swift for handling plurals. Additionally, I'm curious to know if R.swift has any plans to support String Catalog, or even implement automatic grammar agreement? |
To generate a R.swift method for this key, we should be able to The localization system of Swift, use ExpressibleByStringInterpolation everywhere. LocalizedStringResource The problem is none of them have any other init to pass key and argument types. I achieved this by utilizing LocalizedStringResource.init with defaultValue which requires iOS 16. let carKey: LocalizedStringResource = .init("%lld car", defaultValue: "\(2)")
print(String(AttributedString(localized: carKey).characters))
// prints: 2 cars I tried other examples. On this case there are multiple plural and the order of objects are different on different localizations.
let enKey: LocalizedStringResource = .init("pen_and_book", defaultValue: "\(1)\(2)", locale: .init(identifier: "en"))
print(String(AttributedString(localized: enKey).characters))
// prints: 1 pen and 2 books
let frKey: LocalizedStringResource = .init("pen_and_book", defaultValue: "\(1)\(2)", locale: .init(identifier: "fr"))
print(String(AttributedString(localized: frKey).characters))
// prints: 2 livres et 1 stylo This method can also replace NSLocalizedString completly (after iOS 16)
let key: LocalizedStringResource = .init("hello_with_name", defaultValue: "\("World")")
print(String(localized: key))
// prints: Hello World! This is a prelimenery extensions to convert Rswift String resources to String and Attributed String. @available(iOS 16, *)
extension RswiftResources.StringResource1 {
// defaultValue does not support CVarArg protocol. I could not find a suitable protocol.
func localizedStringResource(_ arg1: Arg1) -> LocalizedStringResource where Arg1 == String {
switch source {
// Cannot pass bundle inside of source. Its type is different.
case let .selected(_, locale):
return .init(self.key, defaultValue: "\(arg1)", table: self.tableName, locale: locale, comment: self.comment)
default:
return .init(self.key, defaultValue: "\(arg1)", table: self.tableName, comment: self.comment)
}
}
func localizedStringResource(_ arg1: Arg1) -> LocalizedStringResource where Arg1 == Int {
switch source {
case let .selected(_, locale):
return .init(self.key, defaultValue: "\(arg1)", table: self.tableName, locale: locale, comment: self.comment)
default:
return .init(self.key, defaultValue: "\(arg1)", table: self.tableName, comment: self.comment)
}
}
}
@available(iOS 16, *)
extension LocalizedStringResource {
var asString: String {
.init(localized: self)
}
var asAttributedString: AttributedString {
.init(localized: self)
}
}
extension AttributedString {
var asString: String {
.init(self.characters)
}
} How to use: print(R.string.localizable.lldCar.localizedStringResource(5).asAttributedString.asString)
// prints: 5 cars
print(R.string.localizable(preferredLanguages: ["fr"]).lldCar.localizedStringResource(5).asAttributedString.asString)
// prints: 5 voitures Currently there is SwiftUI extension of Rswift, however, they lose inflect information. This implementation fixes that problem. @available(iOS 16, *)
extension Text {
public init<Arg1: CVarArg>(_ resource: StringResource1<Arg1>, _ arg1: Arg1) where Arg1 == String {
self.init(resource.localizedStringResource(arg1))
}
public init<Arg1: CVarArg>(_ resource: StringResource1<Arg1>, _ arg1: Arg1) where Arg1 == Int {
self.init(resource.localizedStringResource(arg1))
}
} Text(R.string.localizable.lldCar, 5)
// displays: 5 cars |
For example, when I define the string
"%lld person" = "^[%lld person](inflect: true)";
in localizable.string, and call it with theR.string.localizable.lldPerson(2)
, it will return^[2 person](inflect: true)
, not the2 people
as I expected.To leverage the automatic grammar agreement, I need to define the following:
Use the R.swift to get the translation:
So that it will return "2 people", which is translated and pluralized.
Is there any better way to do that?
The text was updated successfully, but these errors were encountered: