70

I am learning to localise my app to Simplified Chinese. I am following this tutorial on how to do this.

Because the tutorial is based on Obj-C, formatted strings can be written like this:

"Yesterday you sold %@ apps" = "Ayer le vendió %@ aplicaciones";

"You like?" = "~Es bueno?~";

But I am using Swift. And in Swift I don't think you can use %@ to indicate that there is something to be placed there. We have string interpolation right?

My app is kind of related to maths. And I want to display which input(s) is used to compute the result in a detailed label of a table view cell. For example

--------------
1234.5678
From x, y <---- Here is the detailed label
--------------

Here, From x, y means "The result is computed from x and y". I want to translate this to Chinese:

从 x, y 得出

Before, I can just use this:

"From \(someVariable)"

with the strings file:

"From" = "从 得出";

And this is how I would use it in code

"\(NSLocalizedString("From", comment: "")) \(someVariable)"

But if this were used in the Chinese version, the final string will be like this:

"从 得出 x, y"

I mean I can put the and 得出 in two different entries in the strings file. But is there a better way to do it?

5 Answers 5

85

You can use %@ in Swift's String(format:...), it can be substituted by a Swift String or any instance of a NSObject subclass. For example, if the Localizable.strings file contains the definition

"From %@, %@" = "从 %@, %@ 得出";

then

let x = 1.2
let y = 2.4
let text = String(format: NSLocalizedString("From %@, %@", comment: ""), "\(x)", "\(y)")
// Or alternatively:
let text = String(format: NSLocalizedString("From %@, %@", comment: ""), NSNumber(double: x), NSNumber(double: y))

produces "从 1.2, 2.4 得出". Another option would be to use the %f format for double floating point numbers:

"From %f, %f" = "从 %f, %f 得出";

with

let text = String(format: NSLocalizedString("From %f, %f", comment: ""), x, y)

See Niklas' answer for an even better solution which localizes the number representation as well.

Sign up to request clarification or add additional context in comments.

7 Comments

Is there a way to specify the order of the parameters or insert a single parameter multiple times? In some languages the insertion order might be reversed. Android allows this by using %1 and %2 before the format specifier.
Is using %@ better than %s (for strings)?
@Suragch: There are encoding problems with %s, see stackoverflow.com/a/23672885 for an example. – I think that positional parameters like %1$s work here as well.
This code won’t localize the numbers themselves — for example in German they use periods for commas and vice-versa, and in Arabic their digits are different codepoints. Use String.localizedStringWithFormat() or String(format: "%f", locale: Locale.current, number) instead.
@WilShipley: You are completely right. Perhaps that method did not exist then or I did not think about it. I still think that I answered the question "I don't think you can use %@ to indicate that there is something to be placed there", but I have added a link to the better solution.
|
62

From WWDC 2017:

let format = NSLocalizedString("%d popular languages", comment:"Number of popular languages")
label.text = String.localizedStringWithFormat(format, popularLanguages.count)

2 Comments

I believe this is the best answer because String.localizedStringWithFormat(_, ...) will localize the actual digits of the numbers (and swap commas and periods for German, for example), and String(format:...) will not. You can also use String(format: "%f", locale: Locale.current, number).
what if the variables to be substituted are in CVarArg?
5

New in iOS 15 and macOS Monterey you can use the new refined method for String.

String(localized: "From \(x), \(y)", comment: "The result is computed from x and y")

They did a lot of updates in 2021 for localization with Xcode. Check this video from WWDC21 for more info.

https://developer.apple.com/videos/play/wwdc2021/10221/

Comments

5

Swift localize a string

One more simple example

let changeable = "something"
let result = String(
    format: NSLocalizedString(
        "stringId",
        comment: ""
    ),
    arguments: [changeable]
) // Hello World and something

//or

let result = String.localizedStringWithFormat(NSLocalizedString("stringId", comment:""), changeable)

localizable.strings with

"stringId" = "Hello World and %@";
  • comment parameter doesn't have effect on result and is used for translators and by genstrings code-gen as comment

Comments

-5

In objective C, if we want to get strings added at runtime as below

John Appleseed is the name

YourLocalizable.strings

"theStringToDisplay" = "%@ is the name";

ViewController.m

NSString *username = @"John Appleseed";
NSString *messageBeforeFormat = NSLocalizedStringFromTable(@"theStringToDisplay", @"YourLocalizable", nil);
NSString *messageAfterFormat = [NSString stringWithFormat:messageBeforeFormat, username ];

self.yourLabel.text = messageAfterFormat;

Further explanation in this nice post

https://www.oneskyapp.com/academy/learn-ios-localization/2-format-strings-plurals/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.