Description
Summary
Initializing a String
or StringResource
with a regular String
key would allow for 'as safe as possible' support for dynamic keys.
Description
In quite some apps, some text can be different based on some dynamic variable. For example, in an app I'm currently working on, we have explanations that differ per region (e.g. Netherlands, United Kingdom and France). Tax rules vary wildly in these regions, but we still show a summary of those in the "same screen". So what happens is that we decide which string is shown based on a region suffix in the translation key;
"tax.rules.NLD" = "The Dutch rules explained.";
"tax.rules.GBR" = "The British rules explained.";
"tax.rules.FRA" = "The French rules explained.";
And then we select between these based on a global 'current region' variable;
let key = "tax.rules.\(currentRegion.alpha3)"
let string = NSLocalizedString(key)
// Often shortened through a convenience getter
Localization.regionalized("tax.rules")
Switching to R.swift would be nicer if this could somehow be integrated there as well. The main thing that we would like to achieve is to still have all the conformances that StringResource provides, with the only exception being the compile-time safe key
.
Possible directions
One way to achieve this is to add more String initializers to also take a regular String
for their keys. This would allow us to do something like the following;
extension StringResource {
public func regionalized() -> String {
@Dependency(\.regionSettings) var regionSettings
let region = regionSettings.settings().countryCodeIsoAlpha3.uppercased()
let key = String(staticString: self.key).dropLast(region.count).appending(region)
return .init(key: key, tableName: tableName, source: source, developmentValue: developmentValue, locale: nil, arguments: [])
}
}
Alternatively, a discussion with @tomlokhorst also surfaced the option to provide an overloaded initializer for StringResource that allows this. This would be similar to what Apple does for LocalizedStringResource. However, this would probably change the ergonomics of the common usecase R.string.someTable.stringResource()
.