[swift-evolution] Localization support for string interpolation
daniel at hoepfl.de
Thu Apr 21 02:42:06 CDT 2016
TL;DR: Here’s my idea for a better localized strings handling in Swift.
It includes both, support for string interpolation support for
NSLocalizedString, and a new string delimiter `...` that can be used
instead of NSLocalizedString("...").
Markdown hard to read? See
# Localization support for string interpolation
I'd like to see some kind of advanced localization support in the Swift
standard library. Currently all we have is what Cocoa provides but that
does not work well with string interpolation. More or less, you can not
use string interpolation if you have to use `NSLocalizedString` and friends.
[I implemented a proof of
`DHLocalizedString`, that fills this gap. I would like to see something
similar being part of the Swift standard library. While it is possible
to implement localized strings as a custom library, this lacks support
from genstring and other tools.
I’m not sure if `NSLocalizedString` is considered part of the Swift
standard library (being part of Foundation Functions). Since there is
decent Unicode-string support in Swift, I would like to see localization
as part of the language, too. This proposal also includes a new string
delimiter `` ` `` that deeply integrate localized strings in the language.
String interpolation greatly simplyfies text handling but makes it hard
to localize. You can not pass a string with interpolation to
`NSLocalizedString` because the key could be unpredictable.
## Proposed solution
`NSLocalizedString` should be extended to work with string interpolation:
let quote = "Never trust the internet!"
let person = "Albert Einstein"
print(NSLocalizedString("<\(quote)> by <\(person)>"));
should look up the key:
```"<%@> by <%@>" = "%2$@ said: “%1$@”";```
```Albert Einstein said: “Never trust the internet!”```
So, `NSLocalizedString` (and friends) would “just work” with string
interpolation. I’m not sure about the key format to use but my proof of
concept simply replaces every interpolation with `%@` which seems
The proof of concept also includes an postfix operator `|~` (think of a
flag) to reduce the impact localized strings have in line length.
Actually, I would love to replace `"` by a different marker (e.g.
`~|string|~`, `''string''`, ``` ``string`` ```, or `` `string` ``?) for
localized strings. Imagine you could write the previous example as:
print(`<\(quote)> by <\(person)>`);
This syntax needs some work on how to specify `tableName:`, `bundle:`,
and `comment:`. For `tableName:` and `bundle:`, I'd love to have a
construct to specify it for all localization tags within the file (e.g.
`#localization(tableName: ..., bundle: ...)`).
If Swift gets multiline strings (`"""string"""`), `` `string` `` could
also have ```` ```multiline``` ````.
## Impact on existing code
I see very little impact. There might be code out there that uses a
interpolated string as argument for `NSLocalizedString`. The key used in
this case would change, breaking the translation. It would be possible
to include a check for interpolated strings as arguments to
`NSLocalizedString` calls in the code update tool.
## Alternatives considered
### Use `NSLocalizedString` as is
One can use `NSLocalizedString` as it was used in Objective-C but this
means that string interpolation cannot be used.
### `localized()` function for String class
I did not find a way how to get the function called before the string
interpolation took place. (`"<\(quote)> by <\(person)>".localized()`)
### Custom function
See above: The drawbacks are: Not having support in standard tools and
the operator syntax not being as good as it could be.
More information about the swift-evolution