Kristof Van Landschoot
Kristof Van Landschoot

Reputation: 1455

Localizing String with placement holders in Swift

Using Swift 3, deployment target iOS 9 or 10. Tested this on both.

Why does:

    let s = "8 août 2017" 
    let sUtf8 = (s as NSString).utf8String!
    let template = "%1$s"
    let s1 = String(format: template, arguments: [sUtf8])
    NSLog(s1)
    let s2 = String.localizedStringWithFormat(template,((s as NSString).utf8String)!)
    NSLog(s2)

log "8 ao√ªt 2017" instead of "8 août 2017"?

Upvotes: 0

Views: 113

Answers (1)

OOPer
OOPer

Reputation: 47896

Please check the Apple's documentation of String Format Specifiers.

%s Null-terminated array of 8-bit unsigned characters. Because the %s specifier causes the characters to be interpreted in the system default encoding, the results can be variable, especially with right-to-left languages. For example, with RTL, %s inserts direction markers when the characters are not strongly directional. For this reason, it’s best to avoid %s and specify encodings explicitly.

(Bold style added.)

There's no guarantee that the passed byte sequence is interpreted as UTF-8.

The UTF-8 byte sequence for "8 août 2017" (in hexadecimal):

38 20 61 6f c3 bb 74 20 32 30 31 37

If your device's default encoding is set to ISO-Latin1, the bytes are interpreted as:

(The system default encodings may be different in users' devices.)

8     a  o  √  ª  t     2  0  1  7

Generally useful guideline: Never use %s in your Swift code.


In Swift code, use %@ instead. (I recommend to use %@ in Objective-C as far as possible.)

let s = "8 août 2017"
let template = "%1$@"
let s1 = String(format: template, s)
NSLog(s1) //->8 août 2017
let s2 = String.localizedStringWithFormat(template, s)
NSLog(s2) //->8 août 2017

You have no need to use ugly and risky(*) (s as NSString).utf8String.


(*) The lifetime of C-string region for .utf8String may be shorter than the string object. And, in Swift, the lifetime of the string object may be far shorter than that in Objective-C.

Upvotes: 2

Related Questions