Xcode での静的ライブラリのローカライズを考える

SPECIAL


静的ライブラリをローカライズ可能にするには

ローカライズ情報を静的ライブラリに持たせる上での課題

アプリケーションであれば、ローカライズしたいばあには "Localizable.strings" ファイルを用意して、そこに文字列のローカライズを定義してあげれば、NSLocalizedString マクロを使って簡単に、ローカライズの対応を取ることが可能です。

ただ、機能を幾つかの静的ライブラリに分割して再利用を考えた場合には、静的ライブラリ内の関数で使用する文字列については、静的ライブラリ自身でローカライズを行うのが自然です。

 

ただ、Xcode 4.1 では、静的ライブラリに Strings ファイルをバンドルすることができないため、静的ライブラリ内にローカライズ文字列情報を保持することができないようです。

ローカライズ文字列は、実行時にその実行環境に合わせた文字列が取得されるため、ローカライズ文字列を保持した Strings ファイルをバンドル内に持っていなければいけません。

そうなると、Strings ファイルをバンドルできるのは、静的ライブラリをリンクする先のアプリケーションしかないので、リンクする静的ライブラリに対応したローカライズ情報を保存した Strings 情報を、アプリケーション側に用意しなければならなくなってきます。

 

そのとき、静的ライブラリの文字列情報も、アプリケーションと同じ "Localizable.strings" ファイル内で管理するのは、静的ライブラリの更新などでローカライズ情報が変更になった場合に、該当する文字列を差し替えなければいけなくなるなど、保守の面で現実てきではなさそうです。

静的ファイル毎に Strings ファイルを用意して、それをアプリケーションに配置する

そこで、静的ライブラリ毎に Strings ファイルを作成して、それをアプリケーションのバンドルに取り込む方法を考えます。

なお、Strings ファイルの準備の仕方や、それを使う方法についての詳細は、strings ファイルを使って文字列をローカライズする の方に記してありますので、必要に応じて参考にしてみてください。

 

まず、静的ライブラリのプロジェクト内で、"静的ライブラリ名.strings" という名前の Strings ファイルを用意して、そこにその静的ライブラリが使用するローカライズ情報を記載しておきます。

そしてこれを、アプリケーション側のプロジェクトに追加してあげる方法を取れば、他のローカライズ情報と明確に分離されるので、差し替え等も比較的簡単に行うことができるようになると思います。

アプリケーション側に追加するときに、コピーではなくリファレンスとして登録すれば、ライブラリ側のプロジェクトでその Strings ファイルを更新するたびに、それがアプリケーション側でも認識されるので便利です。

 

そのような前提で静的ライブラリをローカライズする場合、静的ライブラリ内のローカライズが必要な個所では、次のようなコードを記載して、自分用の Strings ファイルからローカライズ文字列を取得するような記載にします。

[[NSBundle mainBundle] localizedStringForKey:@"ローカライズしたい文字列" value:nil table:@"ライブラリ名"]

このように表記しなければいけないのは、静的ライブラリに関するローカライズ情報が "Localizable.strings" 内にはなく、標準の NSLocalizedString マクロが使用できないためです。

ただ、毎回このような方法でローカライズ文字列を取得するのは大変なので、次のような "EzLocalize" クラスを用意してみました。

 

EzLocalize.h

#define EzLocalizedString(key,libname)    [EzLocalize stringForKey:key library:libname]

 

@interface EzLocalize : NSObject

{

}

 

+ (NSString*)stringForKey:(NSString*)argKey library:(NSString*)argLibrary;

EzLocalize.m

#import "EzLocalize.h"

 

@implementation EzLocalize

 

+ (NSString*)stringForKey:(NSString*)argKey library:(NSString*)argLibrary

{

return [[NSBundle mainBundle] localizedStringForKey:argKey value:nil table:argLibrary];

}

 

@end

たとえばこのようなクラスを用意した場合には、EzLocalize.h の冒頭で定義したマクロを使って、従来の NSLocalizedString と似た書式で、次のようにローカライズ文字列を使用することができるようになります。

EzLocalizedString(@"ローカライズしたい文字列", @"ライブラリ名")

このようにローカライズ文字列を利用できれば、準備の手間が少しばかりかかるものの、その後は従来のように簡単に、ローカライズ文字列を扱うことができるようになると思います。

このような方法方でローカライズを実装した静的ライブラリをリンクしたときにも、その静的ライブラリ用の Strings ファイルをプロジェクトに投げ込んであげるだけで静的ライブラリのローカライズが完了するので、まるで既にローカライズされていたかのように、静的ライブラリを利用する事ができるようになると思います。