SPIDERPLUS Tech Blog

建設SaaS「スパイダープラス」のエンジニアとデザイナーのブログ

m17n アプリケーションの多言語


Xin chào. Tôi là Hirano.

こんにちは、エンジニアリングマネージャーの平野です。

「m17n」という表現はご存知でしょうか?
Multilingualization=多言語化のことで、頭のmとお尻のn、その間に17文字あることから、m17nと表現されています。

当社では昨年、ベトナムに子会社を開設しており、プロダクトの多言語化も進めています。そこで今回は、アプリケーションの多言語化についてご紹介します。

プラットフォーム別の対応

SPIDERPLUSはiOSアプリとWebアプリを提供していますので、それぞれにおける対応についてご紹介します。

iOSアプリ

iOSアプリの多言語化対応では `Localizable.strings`、あるいは最近では `Localizable.xcstrings` というファイルに、key-value形式で言語別のワードリソースを定義します。
XCode15以降を利用する場合はxcstrings(XCString Catalog)が利用できます。
それまでは言語毎のファイルをいちいち開いて、key-valueの定義漏れがないか確認する必要がありました。
XCString Catalogでは、言語毎の翻訳状況を一覧で確認できるようになり、大変便利になりました。

実装ファイル側では `NSLocalizedString(key, comment)` を利用して、定義したワードリソースをロードする、というのが一般的な手法かと思います。

iOS15以降のSwiftでは`String(localized keyAndValue: )`、SwiftUIでは `Text(_ keyAndValue: )` が利用できますので、スッキリと書くことができますね。

SPIDERPLUSではソースコードのファイル数が多く、`Localizable.strings` ファイル1つではファイルが大きくなりすぎてファイル操作が重たくなる、翻訳状況の見通しが悪くなる、ということがあります。
そのため、`ViewController.strings`、`SubViewController.xcstrings`、というように、実装ファイル毎にstringsファイル(xcstringsファイル)を作成しています。
実装ファイル側では `NSLocalizedString(key, tableName, comment)` を利用してワードリソースをロードします。

SPIDERPLUSはUIKitで実装されていますので、ユーザーインターフェースはxibファイルやstoryboardファイルで定義されています。
これらのファイルの翻訳対応には、UIコンポーネントの `Object ID.text` をキーとして翻訳を当てていきます。

このObject IDに対して

このように

結果は下のように表示されます。

一般的な手法かと思いますが、iOSアプリの多言語対応はこのようにして実現しています。

webアプリ

SPIDERPLUSのwebアプリでは便利なフレームワークは利用しておらず、独自で翻訳機能を実現しています。

表示言語はブラウザの言語設定を利用しますが、表示言語変更のUI操作によってその設定値を変更できるようにしています。

翻訳表示をするために実装していることは大きく4つあります。

  1. 言語別の辞書ファイルを追加
  2. HTMLに翻訳表示用のCustomElementを追加
  3. JavascriptPHPに翻訳メソッドを追加
  4. JavascriptにHTMLのCustomElementを翻訳するメソッドを追加

Webアプリの多言語対応でも、iOSと同じくkey-value形式でワードリソースを扱っていますが、日本語ワードをキーとするようにしています。
これにより、翻訳の漏れがあっても、少なくとも日本語では表示できるようになっています。
JavascriptPHPの翻訳メソッドでは、表示言語の設定値を参照して、設定値に対応する各言語の辞書ファイルをロードし、キーに対応するワードリソースを検索して返します。
このとき、表示言語が日本語に設定されていれば、キーをそのまま返します。
また、キーに対応するワードリソースが辞書ファイル内に見つからない場合も、キーをそのまま返します。
工夫した点として、JavascriptPHPで共通の辞書ファイルを利用できるようにしたことがあります。
辞書ファイルを一元管理することで、同じ翻訳を複数箇所で定義してしまうこと、またそれにより修正のたびに両方を変更しなければならない、といったことを回避することができました。
具体的な実装例をご提示できず恐縮ですが、Webアプリの多言語化はこのようにして実現しています。

ワードリソースの定義で気をつけたいこと

ワードリソースを定義するにあたって気をつけておきたいことがあります。
変数を含む場合の対応です。

このユーザーは{会社名}の{雇用形態}です。

たとえばこのメッセージの場合、会社名は「SpiderPlus&Co.」、雇用形態を「正社員」とすると、英語では以下のように表示したいはずです。

The user is a regular employee of SpiderPlus&Co.

これに対して、変数の前後を別々に翻訳してしまうと、

このユーザーは: The user is a
の: of 
です。: .

何だか無理矢理当てた感じになってしまいました。
しかも日本語の場合とは変数の値を翻訳に反映したい順番が異なります。
上記のようなことをやってしまうと、間違った表示になりかねません。

The user is a SpiderPlus&Co. of regular employee.

「このユーザーは正社員のSpiderPlus&Co.です」
そのため、変数を含むメッセージの場合は、書式指定子も含んだキーを定義し、翻訳を行う必要があります。

困ったこと

上述の変数を含む翻訳もその1つですが、多言語化を行う上でいくつか困ったことがありましたので、事象と対処についてご紹介します。

リソースのファイルパス

日本語前提で作られたアプリケーションであるが故に、画像ファイルやExcelファイルなどのリソースが言語別に配置できる。
そのため「ja」「en」「vi」など言語コード名のディレクトリを作成して配置し直し、参照パスを変更するという方法で解決しました。

テキスト埋め込みの画像ファイル

昔からよくあるリソースの表現方法だとは思いますが、多言語化を行う上では厄介です。言語毎に画像ファイルを作成しなければなりません。
SPIDERPLUSでもいくつかの画像リソースはこの手法がとられていたため、テキストのない画像ファイルを作り直し、辞書ファイルで定義したテキストを重ねて表示するように変更しました。

Push通知やメールの言語

SPIDERPLUSは日本語で作られて、日本語で使われてきたため、日本語が前提になっており、ユーザーが使用する言語がデータとして保存されていませんでした。
これでは、通知を行う場合は送信側の表示言語設定に依存するしかなく、受信側にとってはフレンドリーではありません。
そのため、ユーザー情報を扱うDBテーブルに利用言語のカラムを追加しました。このカラムを参照することで、送信先の相手に応じた言語で送信することができます。

まとめ

以上のようなことに取り組みながら、SPIDERPLUSの多言語化を進めています。
これからアプリケーション開発を行われる方は、海外展開は絶対にない、という場合を除いて、m17nを考慮した設計にされることをオススメします。
後から、やっぱり多言語化しよう、ということになると、実装変更箇所が多くなり、テストの規模も大きくなってしまいますので。

それでは、また。

Hẹn gặp lại.


スパイダープラスでは仲間を募集中です。
スパイダープラスにちょっと興味が出てきたなという方がいらっしゃったらお気軽にご連絡ください。