Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Swift and localizedStringWithFormat

I could not find a substitute for localizedStringWithFormat in swift. What I am trying to do is to use the singular/plural localization using the Localizable.stringsdict, english example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>%d record trovati</key>
        <dict>
            <key>NSStringLocalizedFormatKey</key>
            <string>%#@num_people_in_room@ in the room</string>
            <key>num_people_in_room</key>
            <dict>
                <key>NSStringFormatSpecTypeKey</key>
                <string>NSStringPluralRuleType</string>
                <key>NSStringFormatValueTypeKey</key>
                <string>d</string>
                <key>zero</key>
                <string>No record</string>
                <key>one</key>
                <string>Only one record</string>
                <key>other</key>
                <string>Some records</string>
            </dict>
        </dict>
    </dict>
</plist>

and the code:

[NSString localizedStringWithFormat:NSLocalizedString(@"%d record trovati", nil), totRecsFound];

Any idea on how to do this in Swift?

like image 775
valfer Avatar asked Sep 16 '14 07:09

valfer


2 Answers

The same methods are available in Swift:

for totRecsFound in 0 ... 3 {
    let str = NSString.localizedStringWithFormat(NSLocalizedString("%d record trovati", comment: ""), totRecsFound)
    println(str)
}

Output:

No record in the room
Only one record in the room
Some records in the room
Some records in the room

Note that in addition to the "Localizable.stringsdict" file there needs to be a "Localizable.strings" file (which may be empty).

Update for Swift 3/4:

for totRecsFound in 0 ... 3 {
    let str = String.localizedStringWithFormat(NSLocalizedString("%d record trovati", comment: ""), totRecsFound)
    print(str)
}
like image 70
Martin R Avatar answered Oct 19 '22 06:10

Martin R


I wrote an extension for easy use:

extension NSString {
  static func localizedStringForPlurals(formatKey key: String, comment: String = "", args: CVarArg... ) -> String
{
    let format = NSLocalizedString(key, comment: comment)
    let result = withVaList(args){
        (NSString(format: format, locale: NSLocale.current, arguments: $0) as String)
    }

    return result
}

Here are some usages:

for totRecsFound in 0 ... 3 {
  let str = String. localizedStringForPlurals(formatKey: "%d record trovati", comment: "my comments", args: totRecsFound)
  println(str)
}
// Or
for totRecsFound in 0 ... 3 {
  let str = String. localizedStringForPlurals(formatKey: "%d record trovati", args: totRecsFound)
  println(str)
}

In case you have more than one numeric values in a key(you have to specify each variable in your resource file as in the following example), you can this method to pass more than one number arguments to get localized string.

Here is the fun part:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>record in room</key>
    <dict>
        <key>NSStringLocalizedFormatKey</key>
        <string>%#@num_people_in_room@ in %#@room@ (%#@comment@)</string>
        <key>num_people_in_room</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>d</string>
            <key>zero</key>
            <string>No record</string>
            <key>one</key>
            <string>Only one record</string>
            <key>other</key>
            <string>Some records</string>
        </dict>
        <key>room</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>d</string>
            <key>zero</key>
            <string>none room</string>
            <key>one</key>
            <string>%d room</string>
            <key>other</key>
            <string>%d rooms</string>
        </dict>
        <key>comment</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>d</string>
            <key>zero</key>
            <string>Weird case: how 0 record in > 0 rooms or 0 room with > 0 records?</string>
            <key>one</key>
            <string>Weird case: how 1 record in > 2 rooms?</string>
            <key>other</key>
            <string>%dth or normal case: OK</string>
        </dict>
    </dict>
</dict>
</plist>

Example codes:

var c = 2
for r in 0 ... 2 {
  for m in 0 ... 2 {
    switch (true) {
      case (r == 0 && m > 0) || (r > 0 && m == 0):
        c = 0
      case r == 1 && m > 1:
        c = 1
      default:
        c = 2
    }
    let str = String. localizedStringForPlurals(formatKey: "record in room", args: r, m, c)
    println(str)
  }
}

Print result:

No record in none room (Normal case: OK)
No record in 1 room (Weird case: how 0 record in > 0 rooms or 0 room with > 0 records?)
No record in 2 rooms (Weird case: how 0 record in > 0 rooms or 0 room with > 0 records?)
Only one record in none room (Weird case: how 0 record in > 0 rooms or 0 room with > 0 records?)
Only one record in 1 room (Normal case: OK)
Only one record in 2 rooms (Weird case: how 1 record in > 2 rooms?)
Some records in none room (Weird case: how 0 record in > 0 rooms or 0 room with > 0 records?)
Some records in 1 room (Normal case: OK)
Some records in 2 rooms (Normal case: OK)

See CLDR: Language Plural Rules for English.

like image 2
David.Chu.ca Avatar answered Oct 19 '22 05:10

David.Chu.ca