# General Translation Knowledge Base: String Catalog を使って iOS アプリをローカライズするには？
URL: https://generaltranslation.com/ja/kb/localize-ios-app.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Xcode で言語を追加し、SwiftUI の Text や String(localized:) などのローカライズ可能な API でユーザー向けテキストを記述してからビルドすると、Xcode がそれらの文字列を String Catalog（.xcstrings）に収集します。翻訳は Xcode 上または XLIFF 経由で行えます。リリースに合わせてカタログを更新し、Web サイトや Android アプリと用語を共有したい場合は、General Translation の CLI を使用してください。
Category: 国際化
Last updated: 2026-10-20
Authors: Kevin Wu, Jackie Chen
Published: 2026-10-20

String Catalog は、すべての言語の文字列テーブルを 1 つの JSON ファイルにまとめて保持し、Xcode はビルドのたびにこのファイルをコードと同期します。つまり、残る作業は 2 つです。ユーザー向けの文字列をすべてカタログに取り込むことと、質の高い翻訳をカタログに反映することです。

## Xcode でローカライゼーションを設定する

### 言語を追加する

プロジェクトエディタでプロジェクトを選択し、**Info** を開いて、**Localizations** の下にある追加ボタンをクリックします (String Catalog エディタのサイドバーにも同じボタンがあります) 。各エントリには `de`、`ja`、`en-IN` などの言語 ID が割り当てられます ([Apple: Adding support for languages and regions](https://developer.apple.com/documentation/xcode/adding-support-for-languages-and-regions)) 。リージョン別バリアントは、`pt-BR` と `pt-PT` のようにテキストに違いがある場合にのみ選択してください ([ロケールコード](/docs/platform/core/guides/locale-codes)を参照) 。

### String Catalog を追加してビルドする

**File &gt; New &gt; File from Template** を選択し、「string」で絞り込んで **String Catalog** を選びます。デフォルトの名前は `Localizable.xcstrings` です。次に **Product &gt; Build** を選択すると、Xcode がコード内のローカライズ可能な文字列を検出してカタログに追加します。以降もビルドのたびにカタログが更新されます ([Apple: Localizing and varying text with a string catalog](https://developer.apple.com/documentation/xcode/localizing-and-varying-text-with-a-string-catalog)) 。

String Catalog は Xcode 15 で導入されました ([リリースノート](https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes)) 。ビルド時に `.strings` ファイルと `.stringsdict` ファイルにコンパイルされるため、導入にあたって最小デプロイターゲットを引き上げる必要はありません ([WWDC23: Discover String Catalogs](https://developer.apple.com/videos/play/wwdc2023/10155/)) 。

### ローカライズ可能なAPIでテキストを記述する

Xcodeが抽出するのは、ローカライズ可能なAPIに渡された文字列のみです。SwiftUIでは、ビュー内の文字列リテラルは[`LocalizedStringKey`](https://developer.apple.com/documentation/swiftui/localizedstringkey)値として扱われるため、自動的に抽出されます。それ以外の箇所では、`String(localized:)`を使用してください ([Apple: Preparing your app&#39;s text for translation](https://developer.apple.com/documentation/xcode/preparing-your-apps-text-for-translation)) 。

```swift
import SwiftUI

struct CartView: View {
    let itemCount: Int
    let couponCode: String

    var body: some View {
        VStack {
            // SwiftUI ビュー内の文字列リテラルは LocalizedStringKey 値であるため、
            // ビルド時に Xcode が String Catalog に追加します。
            Text("Your cart")

            // 補間は書式指定子 (%lld) に変換され、複数形に応じて切り替えることができます。
            Text("\(itemCount) items")

            // コメントで、テキストがどこでどのように使われるかを翻訳者に伝えます。
            Text("Checkout", comment: "Button that starts payment for the items in the cart.")

            // String 変数はそのまま表示されます。Text(verbatim:) を使うと、その意図を明示できます。
            Text(verbatim: couponCode)
        }
    }
}

// SwiftUI ビューの外では、String(localized:) でローカライズ可能なテキストを作成します。
let emptyCartMessage = String(
    localized: "Your cart is empty",
    comment: "Shown when the cart has no items."
)
```

よくある見落としが `Text(someString)` です。`String` 型の変数はカタログで参照されません。ビュー間でローカライズ可能なテキストを受け渡すには、`LocalizedStringResource` を使用してください。Apple も推奨している方法で、コメントやテーブル名も一緒に保持できます。

「Checkout」という語だけでは名詞か動詞か判別できないため、コメントは重要です。コメントは `comment:` パラメータで追加できます。また、カタログ内のキーを Control キーを押しながらクリックして **Generate Comment** を選択すると、Xcode が周辺のコードをもとにコメントを生成します。

カタログに登録されていないテキストを見つけるには、**Product &gt; Scheme &gt; Edit Scheme &gt; Run &gt; Options** を開き、**Show non-localized strings** をオンにします。アプリを実行すると、該当する文字列がすべて大文字でレンダリングされます ([Apple: Preparing your interface for localization](https://developer.apple.com/documentation/xcode/preparing-your-interface-for-localization)) 。 ([翻訳されていないハードコードされた文字列を見つけるには？](/kb/find-hardcoded-strings)も参照してください) 。

## 複数形、デバイス、Info.plist を扱う

補間された数値を含むキーを Control キーを押しながらクリックし、**Vary by Plural** を選択します。Xcode は各言語に必要な複数形カテゴリを自動で追加します。英語なら `one` と `other`、ロシア語を追加した場合は `one`、`few`、`many`、`other` です。**Vary by Device** を使うと、1 つのキーにデバイスごとに異なる値を設定できます。たとえば、iPhone では &quot;Tap to learn more&quot;、Mac では &quot;Click to learn more&quot; のように使い分けられます。

エディタの裏側では、カタログは JSON 形式で保存されているため、プルリクエストでも差分がきれいに表示されます。以下は、英語の複数形とスペイン語の翻訳を含む抜粋です。

```json title="Localizable.xcstrings"
{
  "sourceLanguage" : "en",
  "strings" : {
    "%lld items" : {
      "comment" : "Number of items in the shopping cart.",
      "localizations" : {
        "en" : {
          "variations" : {
            "plural" : {
              "one" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "%lld item"
                }
              },
              "other" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "%lld items"
                }
              }
            }
          }
        }
      }
    },
    "Checkout" : {
      "comment" : "Button that starts payment for the items in the cart.",
      "localizations" : {
        "es" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Pagar"
          }
        }
      }
    }
  },
  "version" : "1.0"
}
```

`Info.plist` 内のシステム向けテキスト (アプリの表示名や、権限ダイアログに表示される利用目的の説明など) は、別のカタログで管理します。ターゲットに `InfoPlist.xcstrings` ファイルを追加すると、Xcode がビルドのたびに、ローカライズ可能な既知の `Info.plist` キーをそのファイルに自動で追加します。

## 文字列の状態を追跡する

カタログ内の各翻訳には状態があり、エディターの **State** 列に表示されます。

* **New:** その言語にまだ翻訳されていません。
* **Needs Review:** 翻訳後に翻訳元が変更されたか、誰かがフラグを付けた状態です。現在の値をそのまま使う場合は **Mark as Reviewed** を選択します。
* **Translated:** 緑のチェックマークが表示されます。これ以上の対応は不要です。
* **Stale:** Xcode がコード内でその文字列を検出できなくなった状態です。コードから消えた未翻訳の文字列は削除されますが、翻訳済みの文字列は保持され、削除するまで stale として扱われます。

実行時に組み立てるキーなど、手動で追加した文字列は手動管理に設定できます。手動管理にすると、ビルドによって更新や削除が行われることはありません。

## .strings と .stringsdict から移行する

既存のプロジェクトを変換するには、**Edit &gt; Convert &gt; To String Catalog** を選択します (または、ファイルを Control キーを押しながらクリックして **Migrate to String Catalog** を選択します) 。移行はファイル単位・ターゲット単位で実行されるので、移行作業中もカタログと従来のファイルを共存させられます。ただし、同じターゲット内に同名のカタログと `.strings` または `.stringsdict` ファイルが存在するとビルドエラーになるため、テーブルごとに移行を完了させてから次に進んでください。`InfoPlist.strings` を移行する場合、コメントがあればそのまま引き継がれます。

## 翻訳方法を選ぶ

カタログに翻訳を追加する方法には、次のものがあります。

| 方法                                                 | 翻訳者                 | 翻訳者が得られる文脈                               | リリースごとに繰り返し実行できるか                                                  | 自分で対応する作業                                                 |
| -------------------------------------------------- | ------------------- | ---------------------------------------- | ------------------------------------------------------------------ | --------------------------------------------------------- |
| カタログエディタに入力する                                      | 自分またはバイリンガルのチームメンバー | アプリ全体                                    | いいえ                                                                | すべての言語のすべての文字列の手入力                                        |
| Xcode のコーディングエージェント (Xcode 27)                     | Xcode で有効にしたエージェント  | 各文字列の使用箇所、類似の文字列、複数形の要件、Apple の言語スタイルガイド | Xcode でリクエストごとに実行                                                  | エージェントのセットアップ、機械翻訳された文字列のレビュー、Web アプリや Android アプリとの用語の同期 |
| `.xcloc` と XLIFF をエクスポートして翻訳者または翻訳管理システム (TMS) に渡す | プロの翻訳者              | コメントと、`Notes` フォルダに追加したスクリーンショット         | `xcodebuild` でスクリプト化可能                                             | リリースごとのやり取りと、その待ち時間                                       |
| General Translation CLI                            | GT の翻訳サービス          | カタログのコメントに加え、共有の用語集とカスタムプロンプト            | ビルド前に [`gt translate`](/docs/cli/reference/commands/translate) を実行 | ダッシュボードまたは Xcode でのレビューと、アプリのテスト                          |
| JSON に対して機械翻訳や LLM をスクリプトで実行する                     | モデルまたは翻訳 API        | スクリプトが送信する内容のみ                           | はい                                                                 | バリエーション、置換、言語ごとの複数形カテゴリ、書式指定子、状態、レビュー                     |

**エクスポート。** **Product &gt; Export Localizations** を選ぶと、言語ごとに Xcode Localization Catalog (`.xcloc` フォルダ) が 1 つずつ作成され、その中に XLIFF ファイルが格納されます ([Apple: Exporting localizations](https://developer.apple.com/documentation/xcode/exporting-localizations)) 。すべての Swift 文字列をエクスポートに含めるには、**Use Compiler to Extract Swift Strings** ビルド設定をオンにしてください。翻訳は **Product &gt; Import Localizations** で取り込めます。`xcodebuild -exportLocalizations` と `xcodebuild -importLocalizations` を使えば、エクスポートとインポートの両方をスクリプト化することもできます ([Apple: Importing localizations](https://developer.apple.com/documentation/xcode/importing-localizations)) 。

**Xcode 27 での変更点。** Xcode のエージェントで String Catalog を翻訳できるようになりました。Xcode が言語を追加し、不足している String Catalog を作成したうえで、各文字列の文脈をエージェントに渡します ([Xcode 27 release notes](https://developer.apple.com/documentation/xcode-release-notes/xcode-27-release-notes)、[WWDC26: Translate your app using agents in Xcode](https://developer.apple.com/videos/play/wwdc2026/213/)) 。カタログエディタには **Generate Translations** ボタンが追加され、エージェントの出力には **Machine Translated** 状態が設定されます。エクスポートした XLIFF では、これが `state-qualifier="leveraged-mt"` として示されます。ローカライゼーションコメントに「do not translate」と書くと、その文字列はカタログで **Don&#39;t Translate** に、XLIFF で `translate="no"` になります。また、`AGENTS.md` や `CLAUDE.md` から `TRANSLATION.md` ファイルを参照させ、用語集やエージェントに翻訳させない文字列のリストを渡すこともできます ([Apple: Localizing your app using agents](https://developer.apple.com/documentation/xcode/localizing-your-app-using-agents)) 。

自分で扱える 1〜2 言語だけなら、カタログエディタで十分です。Xcode 内で機械翻訳したい場合は Xcode のエージェントを使いましょう。リポジトリで繰り返し実行できるコマンドや、製品間での用語の共有が重要な場合は General Translation を選んでください。Xcode や Apple ネイティブのローカライゼーション API は引き続きそのまま使えます。プロの翻訳者や既存の [TMS](/kb/what-is-a-translation-management-system) に作業を任せる場合は、XLIFF エクスポートを使いましょう。

## すべての言語をテストする

**Product &gt; Scheme &gt; Edit Scheme** を選択し、**Run**、**Options** の順に開いて、次回の実行で使用する **App Language** と **App Region** を設定します ([Apple: Testing localizations](https://developer.apple.com/documentation/xcode/testing-localizations-when-running-your-app)) 。同じ **App Language** メニューには疑似言語も用意されています。テキストの伸長を確認する **Double-Length**、反転レイアウトを確認する **Right-to-Left**、背の高いグリフを確認する **Accented** と **Tall**、切り詰めを確認する **Bounded String** です ([疑似ローカライゼーションとは？](/kb/pseudo-localization)を参照) 。SwiftUI のプレビューでは、`.environment(\.locale, .init(identifier: "de"))` を設定します。

App Store のメタデータ (名前、説明、スクリーンショット) は、[App Store Connect](https://developer.apple.com/help/app-store-connect/manage-app-information/localize-app-information) で別途ローカライズします。

## General Translation で String Catalog を翻訳する

翻訳を繰り返し実行できるコマンドとして運用し、iOS アプリ、Web サイト、Android アプリの間で用語を統一したい場合は、General Translation の CLI である `gt` を使えば `.xcstrings` ファイルをインプレースで翻訳できます (`gt` 2.21.0 以降) 。`gt.config.json` に `xcstrings` エントリを追加し、各カタログを直接指定します：

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["es", "ja"],
  "files": {
    "xcstrings": {
      "include": ["Resources/Localizable.xcstrings", "Resources/InfoPlist.xcstrings"]
    }
  }
}
```

すべてのロケールが同じファイルに含まれるため、`include` パスには `[locale]` プレースホルダーを含めません。また、カタログの `sourceLanguage` は `defaultLocale` と一致させる必要があります。一致しない場合、実行はアップロード前に停止します。[`npx gt login`](/docs/cli/reference/commands/login) でサインインし、`GT_PROJECT_ID` を設定してください ([CLI の認証情報](/docs/cli/guides/configuring#credentials)) 。既存のアプリでは、[`npx gt upload`](/docs/cli/reference/commands/upload) で翻訳元とレビュー済みの翻訳をインポートします。続いて [`npx gt translate`](/docs/cli/reference/commands/translate) を実行し、更新を生成します。CI では、**Files &gt; Write** と **Translation queue &gt; Enabled** の権限を持つプロジェクトの APIキーを `GT_API_KEY` として保存してください。

CLI はソース言語の部分のみをアップロードし、各対象ロケールの翻訳をファイルにマージします。その際、無関係なロケールやカタログの構造はそのまま保持されます。String Catalog の処理では、バリエーションの翻訳に対象言語の複数形カテゴリを使用し、書式指定子や置換もそのまま保持します ([`.xcstrings` リファレンス](/docs/cli/reference/formats/xcstrings-files)を参照) 。従来のレイアウトでは、代わりに `dotStrings` および `dotStringsdict` キーを使って `.strings` ファイルと [`.stringsdict`](/docs/cli/reference/formats/dot-stringsdict-files) ファイルを翻訳します。

カタログのレビューは、Xcode またはダッシュボードの[生ファイルエディター](/docs/platform/dashboard/guides/reviewing-translations)で行えます。Xcode で翻訳を編集した場合は、[`npx gt save-local`](/docs/cli/reference/commands/save-local) を実行しておくと、以降の実行でも編集内容が保持されます。iOS、Web、[Android](/docs/cli/reference/formats/android-strings-files) の各プロジェクトに同じ[コンテキストグループ](/docs/platform/dashboard/guides/defining-context-for-translations)を割り当てれば、プラン名などの用語集の用語をすべてのユーザー接点で統一できます。

Ramp は、ダッシュボード、ランディングページ、iOS アプリの 11 以上のロケールで GT を活用しています。ひとつの翻訳プラットフォームで Web とネイティブの両製品をカバーしている好例です ([本番環境でのデプロイ事例](https://generaltranslation.com/enterprise)を参照) 。

## 重要なポイント

* `Localizable.xcstrings` を追加したら、一度ビルドしてください。Xcode は SwiftUI のリテラルと `String(localized:)` のテキストを抽出しますが、`String` 変数から生成した `Text` は抽出しません。
* 数量の表示には **Vary by Plural** を使用します。Xcode が言語ごとの複数形カテゴリ (ロシア語なら 4 つなど) を追加します。
* コードから削除された翻訳済み文字列は、消えずに **Stale** として残ります。不要なものは意識的に整理しましょう。
* Xcode 27 では、エージェントによる翻訳、**Machine Translated** 状態、エクスポートした XLIFF の `leveraged-mt` が新たに追加されています。
* General Translation の CLI では、`"xcstrings": { "include": [...] }` を設定して [`npx gt translate`](/docs/cli/reference/commands/translate) を実行すると、カタログをインプレースで翻訳できます。翻訳対象外のロケールやカタログの構造はそのまま保持され、ターゲット言語のバリエーションが生成されます。

## Related questions

- [疑似ローカライゼーションとは？](https://generaltranslation.com/ja/kb/pseudo-localization.mdx): 疑似ローカライゼーションは、原文をアクセント記号付きで約40%長く水増しし、括弧で囲んだ改変版に置き換えるテストです。これにより、ハードコードされた文字列、切り詰め、フォントの表示崩れ、文の連結といった問題を、翻訳を用意する前に発見できます。Android にはこの用途向けに en-XA と ar-XB の疑似ロケールが用意されています。
- [翻訳されていないハードコードされた文字列を見つけるにはどうすればよいですか？](https://generaltranslation.com/ja/kb/find-hardcoded-strings.mdx): CI でリンターを実行し、ユーザー向けの文字列リテラルを検出します。たとえば JSX なら eslint-plugin-i18next の no-literal-string ルール、Android なら Android Lint の HardcodedText チェック、Rails なら erb_lint の HardCodedString リンターが使えます。さらに、疑似ロケールでアプリを一通り操作し、静的チェックでは追跡できないテキストを洗い出します。
- [CSS で RTL（右から左）言語をサポートするには？](https://generaltranslation.com/ja/kb/right-to-left-css.mdx): lang だけでは書字方向は変わらないため、html 要素に dir="rtl" と lang の両方を指定します。そのうえで、margin-left などの物理的な CSS を margin-inline-start などの論理プロパティに置き換えます。flex の行、グリッドの列、デフォルトのテキストの配置は自動的に反転しますが、translateX()、left、right は反転しません。
- [General Translation と TMS（Crowdin、Lokalise、Phrase）の比較](https://generaltranslation.com/ja/kb/general-translation-vs-tms.mdx): 翻訳の生成、コードから導出した文脈、レビューをプロダクトのリリースと連動させたい開発チームには General Translation が適しています。既存のカタログとレンダリングライブラリをそのまま使うことも、翻訳キーを使わずにインライン JSX を記述することもできます。TMS は、言語ベンダー、CAT エディター、XLIFF でのやり取りを中心とした翻訳プログラムに適しており、そのインテグレーションを使えばファイル転送を自動化できます。

## Previous and next questions

- Previous question: [SRT 字幕のタイミングを崩さずに翻訳するには？](https://generaltranslation.com/ja/kb/translate-srt-subtitles.mdx)
- Next question: [ウェブサイトを多言語化するにはどうすればよいですか？](https://generaltranslation.com/ja/kb/make-website-multilingual.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/ja/kb/sitemap.md) for every article.
