しおメモ

雑多な技術系ブログです。ニッチな内容が多いです。

Swiftで作成したiOS向けframeworkをローカライズする

普通のアプリの場合は、NSLocalizedStringにキーを渡すだけで大丈夫なのですが、frameworkを公開する場合、デフォルトだとアプリ側のBundleを参照してしまうので、そちらも正しく指定しなくてはいけません。
情報が少なかったので、その方法を記載しておきます。

やること

普通のアプリと同じように、Localizable.stringsを用意します。
Base.lprojを上手く作ってくれない場合があるかもしれませんが、手動で作ればプロジェクトが読み込んでくれます。

f:id:scior:20190202183509p:plain

そのままBundleを指定せずに、NSLocalizedStringを呼んでしまうと、Bundle.mainの方を呼んでしまうので、Bundle Identifierから参照するようにします。

f:id:scior:20190202183820p:plain

上の部分を参照して、

Bundle(identifier: "com.flyingalpaca.Uppsala")

のように取得します。
自分はローカライズの部分までまとめて、extensionにしました。好みでcomputed propertyにしてもいいと思います。

extension String {
    func localized() -> String {
        guard let bundle = Bundle(identifier: "com.flyingalpaca.Uppsala") else { return self }
        return NSLocalizedString(self, tableName: nil, bundle: bundle, comment: self)
    }
}

すると、このような感じで呼べます。

"update_notification_title".localized()

サンプル

実際に使うときは、このようにenumのメソッドでさらにラップして使っています。

public class Dialog {
    /** いろいろ */
    public init() {
        title = LocalizedStringKeys.notificationTitle.localized()
    }
}

fileprivate extension Dialog {
    enum LocalizedStringKeys: String {
        case notificationTitle = "update_notification_title"
        case notificationMessage = "update_notification_message"

        func localized() -> String {
            return self.rawValue.localized()
        }
    }
}