[SwiftPM] Swift Package の Localization(コード中の文字列対象)

SwiftPackageManagerEyeCatch

Swift Package 化したモジュールの 文字列 の Localization 方法を説明します。

# Apple が Internationalization ではなく Localization と表現しているので、Localization としました。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Monterery beta 4
  • Xcode 13 beta3
  • iOS 15 beta

App の Localization と Swift Package の Localization

App の Internationalization は、以下の記事で説明しました。

[SwiftUI][Xcode] 文字列を Internationalization I18N する

Swift Package 化されたモジュールは、異なる手順が必要となります。

MEMO
App の L10N では、XLIFF フォーマットを Xcode から出力して編集、Xcode に取り込むということでローカライズできましたが、Swift Package では 個々に対応していく必要があります。

Swift Package の L10N 手順

Package.swift で Default Language 指定

Localization される Swift Package は、デフォルトの言語指定を持つ必要があります。

Package 型で、defaultLocalization を設定します。


let package = Package(
    name: "SDSSupportRequestSheet",
    defaultLocalization: "en",   // <- NEW
    platforms: [
        .iOS(.v14),
        .macOS(.v11)
    ],
...

上記では、SDSSupportRequestSheet パッケージのデフォルト言語を 英語に指定しています。

Package.swift で リソースファイル処理追加

defaultLocalization 指定の他にも、Swift Package として、Localization のためのファイル処理を指定する必要があります。

"Resources" というフォルダにリソースをまとめる前提で、以下のように Package.swift に追記します。


let package = Package(
    name: "SDSSupportRequestSheet",
 //..snip..
    targets: [
        .target(
            name: "SDSSupportRequestSheet",
            dependencies: [],
            resources: [.process("Resources")]), // <- NEW
        .testTarget(
            name: "SDSSupportRequestSheetTests",
            dependencies: ["SDSSupportRequestSheet"]),
    ]
)

特定の拡張子を使ってファイルを作成している場合は、Xcode が既知の拡張子であれば内容に従った処理をしてくれますので、.process 指定すれば良いです。

Project に strings ファイル追加

リソースとして、strings ファイルを追加していきます。

デフォルト言語向け設定ファイルとローカライズ言語向け設定ファイルの追加

デフォルト言語を en にしましたので、en 向けのフォルダと設定ファイルを作成します。

さらに必要な分だけ、ローカライズ言語向け設定ファイルを追加していきます。

以下は、デフォルト言語としての en と ローカライズ言語としての ja 向けの設定ファイルを追加したものです。

FolderStructure
FolderStructure
  • フォルダは、言語名称+"lproj" である必要があります
  • ファイルは、Localizable.strings である必要があります
  • ローカライズ言語を追加する場合は、さらに設定ファイルを追加していくことになります。例えば、fr や de を追加していくことで、フランス語やドイツ語が追加できます

上記のフォルダ構成にすると 英語設定の時には、en.lproj/Localizable.strings が参照され、日本語設定の時には、ja.lproj/Localizable.strings が参照されます。

fr や de を追加していないので、フランス語設定やドイツ語設定 等の日本語設定以外では、デフォルトである英語設定 en.lproj/Localizable.strings が参照されることになります。

Localize 対応文字列化

# SwiftUI を前提としています。

コード中の以下の種類の文字列を Localize していく作業になります。

  • String 型として定義された文字列
  • Text 等 SwiftUI で 引数型が LocalizedStringKey と合わせて、bundle 情報を受け取ることができる型で使用される文字列
  • Picker 等 SwiftUI で引数型が LocalizedStringKey だけで、bundle 情報を同時に受け取ることができない型で使用される文字列

String 型として定義された文字列

以下のような置き換えをしていきます。
Localize 対応前:


let str = "Question"

Localize 対応後:


let str = NSLocalizedString("Question", bundle: .module, comment: "")
Tips
Xcode のエディタ上で、文字列を選択し、コンテキストメニュー(右クリックメニュー)で "Refactor" - "Wrap in NSLocalizedString" を選択すると簡単に変換できます。

Text 等 SwiftUI で 引数型が LocalizedStringKey と合わせて、bundle 情報を受け取ることができる型で使用される文字列

以下のような置き換えをしていきます。

Localize 対応前:


Text("Cancel")

Localize 対応後:


Text("Cancel", bundle: .module)

Text の initializer に "bundle: .module" 指定を追加する変更です。この場合の .module は Swift Package を指しています。

Picker 等 SwiftUI で引数型が LocalizedStringKey だけで、bundle 情報を同時に受け取ることができない型で使用される文字列

Picker 等のいくつかの SwiftUI の View は、bundle 指定できる文字列を受け取れないために、NSLocalizedString 化した文字列を渡す必要があり、以下のような置き換えが必要となります。

Localize 対応前:


Picker("type", selection: $selectedType) {
...

Localize 対応後:


Picker(NSLocalizedString("type", bundle: .module, comment: ""), selection: $selectedType) {
...

対応文字列 の Localize

ここまでの作業は、特定の文字列が、言語設定によって変更されることを定義してきました。

続けて、個別の言語設定で個別文字列の翻訳を設定していきます。

デフォルト言語設定

en.lproj/Localizable.strings が設定ファイルとなります。

ファイル中に以下の記述をすることで、"Cancel" が "Cancel" と表示されます。


"Cancel" = "Cancel";

ローカライズ言語設定

日本語を設定する場合は、ja.lproj/Localizable.strings が設定ファイルとなります。

ファイル中に以下の記述をすることで、"Cancel" が "キャンセル" と表示されます。


"Cancel" = "キャンセル";
注意
各行の最後に、";" が必要です。Swift でコードを書いている人は忘れがちなので、注意が必要です。

アプリの言語設定が必要

Swift Package が持っている言語を使用するためには、Swift Package を使用する側の App がその言語設定を持っている必要があります。

例えば、App が日本語設定を持っていなければ、Swift Package が日本語設定を持っていても、使用されることはありません。

まとめ:Swift Package の Localization

Swift Package の Localization
  • Package.swift にデフォルト言語設定と、リソースファイル処理を追加
  • .lproj フォルダに Localizable.strings を作ると、Xcode が適切に処理してくれる
  • NSLocalizableString を使う。SwiftUI の View によっては、直接指定できる
  • 使用される言語設定は、App から引き継がれる(App が対応していない言語のリソースは使用されない)

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です