iOS
国際化
Swift
Xcode6

Xcode 6で導入されたstringsdictファイルを使って、イケてる複数形多言語対応

More than 3 years have passed since last update.

今開発中のPlayer!も英語対応していますが、英語の複数形対応がされていないと、かなり残念な印象を与えてしまうようです。


  • ×: "3 comment"

  • ○: "3 comments"

英語の適切な例:


  • "0 comments"

  • "1 comment"

  • "2 comments"

このように、1かそれ以外で表現が変わります。

日本語だと数に関係無く「3コメント」などで良くて楽ですが、0の時は「0コメント」じゃなくて「コメントなし」にしたいなどもあると思います。

これは簡単な例ですが、「1かそれ以外」で表現が変わる以外に言語によって様々なパターンが存在し、それらに最適化するのは実はかなり大変です。

以下の対応をしている人が多いのではと思っています。


  • 放置


    • "3 comment"を許容



  • 英語だけは対応しておくけど後のことは考えていない


    • 上述の通り、1かそれ以外で切り替える対応だけはする



  • もうちょっとがんばって自作関数作って工夫

  • ライブラリ使う



    • mattt/TTTLocalizedPluralString を見つけました。stringsdict使う方法がベターだと思いますがこちらの方が使い方は簡単です。




Xcode 6で導入されたstringsdict

ここで、Xcode 6で導入されたstringsdictの出番です。

Appleリファレンス: Handling Noun Plurals and Units of Measurement

このように数字によって表示を変えたい場合、

Completed runs
Total Runs
Output

0
0+
No runs completed yet

1
1+
One run completed

1
2+
One of x runs completed

2+
2+
x of y runs completed

stringsdictファイルを定義しておけば、コードは以下だけでOKです。

String.localizedStringWithFormat(NSLocalizedString("StringsDictSampleKey", comment: ""), completed, total)


XXX.stringsdict

stringsファイルとは違って、Plistファイルで構成されます。

XXX部分の命名は、stringsファイルと同じで、隣に置いておけばstringsファイルの言語リソースと同じ関数で呼び出せます。

<!-- 言語ごとに用意 -->

<?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>StringsDictSampleKey</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%1$#@completed_runs@</string>
<key>completed_runs</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>zero</key>
<string>No runs completed yet</string>
<key>one</key>
<string>One %2$#@total_runs@</string>
<key>other</key>
<string>%d %2$#@total_runs@</string>
</dict>
<key>total_runs</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>run completed</string>
<key>other</key>
<string>of %d runs completed</string>
</dict>
</dict>
</dict>
</plist>

国際化対応はもちろん、一言語のみのアプリだとしてもコードで処理分けせずに宣言的に記述出来て良いと思います。

stringsdictファイルについてはがんばれば何が対応しているのが読み取れると思うので細かい説明は省略します。

仕様はこちらご覧ください: Stringsdict File Format

ただ、zerooneotherなどのキー名については気になると思います。

これはlocaleごとに定められていて、Language Plural Rulesに載っているパターンが使えます。

日本語はotherだけしか載ってないですが、それに加えてzeroは共通で使える模様です( ´・‿・`)


残念な点

Xcode 6で対応されたXLIFFフォーマットへのExportはサポート外です(´・ω・`)

詳細: Xcode 6で導入されたXLIFFによる国際化フローは使える? - Qiita


参考資料