Skip to main content

iOS アプリのローカリゼーション完全ガイド

Localizable.strings から App Store メタデータまで。Xcode、SwiftUI、Fastlane、AI 自動翻訳を使用して iOS アプリをローカライズする方法を解説します。

1

Xcode でローカリゼーションを有効化

Xcode のプロジェクト設定を開き、Info > Localizations に移動して、対応する言語を追加します。Xcode により、言語ごとの .lproj ディレクトリが自動的に作成されます。

Xcode Project Settings
// In Xcode:
// 1. Select your project in the navigator
// 2. Go to Info tab > Localizations
// 3. Click + to add languages (e.g., German, Japanese)
// 4. Select which files to localize
//
// Xcode creates .lproj directories automatically:
// en.lproj/Localizable.strings
// de.lproj/Localizable.strings
// ja.lproj/Localizable.strings
Base localization は、UI と表示文字列を分離します。言語を追加すると、storyboard、XIB、文字列ファイルのローカライズ版を作成するかどうかを Xcode で選択できます。
2

Localizable.strings を作成

標準の iOS ローカリゼーションファイルでは、等号で区切ったキーと値のペアを使用し、各行の末尾にセミコロンを付けます。翻訳元の言語用ファイルは Base.lproj フォルダーに配置します。

Base.lproj/Localizable.strings
// Base.lproj/Localizable.strings

"welcome_title" = "Welcome to MyApp";
"login_button" = "Sign In";
"settings_label" = "Settings";
"greeting" = "Hello, %@!";    // %@ = string placeholder
"item_count" = "%d items";     // %d = integer placeholder
セミコロンがないと、エラーが表示されないまま失敗します。ファイルはエラーなく読み込まれますが、翻訳は空になります。また、ターゲットの Copy Bundle Resources ビルドフェーズにファイルが追加されていることを確認してください。追加されていないファイルはアプリバンドルに含まれません。
Common .strings Mistakes
// ❌ Common mistakes in .strings files:

// Missing semicolon — file loads but translations are empty
"welcome_title" = "Welcome"

// Unescaped quotes — causes parse error
"message" = "Click "here" to continue";

// ✅ Correct versions:
"welcome_title" = "Welcome";
"message" = "Click \"here\" to continue";
3

String Catalog へ移行(Xcode 15 以降)

String Catalog(.xcstrings)は、.strings ファイルに代わる Apple の新しい仕組みです。Xcode のビジュアルエディター、SwiftUI ビューからの文字列自動抽出、組み込みの複数形対応を利用できます。

Localizable.xcstrings
// Xcode 15+ String Catalog (Localizable.xcstrings)
// Xcode automatically extracts strings from your code
// and manages translations in a visual editor.

// In SwiftUI, strings are automatically localizable:
Text("Welcome to MyApp")
Text("Hello, \(userName)!")

// Mark strings explicitly:
let title = String(localized: "welcome_title")
String Catalog は、すべての言語を 1 つの .xcstrings JSON ファイルに保存します。チームでは、複数のメンバーが文字列を追加すると Git のマージ競合が頻繁に発生します。大規模プロジェクトでは、モジュールごとにカタログを分けることを検討してください。
4

SwiftUI と UIKit でローカライズ文字列を使用

SwiftUI の Text ビューは、文字列リテラルを自動的にローカライズします。UIKit では NSLocalizedString を使用します。iOS 16 以降では、新しい String(localized:comment:) API により、コンパイラーの組み込みサポートを活用した簡潔な構文を使用できます。

ContentView.swift
import SwiftUI

struct ContentView: View {
    let userName: String

    var body: some View {
        VStack {
            // ✅ SwiftUI auto-localizes string literals
            Text("welcome_title")

            // ⚠️ This does NOT localize (String interpolation)
            // Text("Hello, \(userName)")

            // ✅ Use String(localized:) for dynamic strings
            Text(String(localized: "greeting \(userName)"))

            // ✅ UIKit style (works everywhere)
            let title = NSLocalizedString(
                "settings_label",
                comment: "Settings screen title"
            )

            // ✅ Modern API (iOS 16+)
            let modern = String(
                localized: "welcome_title",
                comment: "Main screen title"
            )
        }
    }
}
name が通常の String 変数の場合、Text("Hello \(name)") は通知なくローカライズに失敗します。SwiftUI の文字列補間では LocalizedStringKey が作成されますが、正しく補間できるのは特定の型(Int、Double など)だけです。String 変数の場合は、まず String(localized:) を使用してローカライズ文字列を作成してください。
5

複数形を処理

iOS は複数形ルールに .stringsdict ファイルを使用し、zero、one、two、few、many、other という CLDR の全カテゴリに対応します。String Catalog では Xcode のビジュアルエディターで複数形を処理できるため、stringsdict XML を手作業で記述するよりも簡単です。

Localizable.stringsdict
<!-- Localizable.stringsdict -->
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
    <key>items_count</key>
    <dict>
        <key>NSStringLocalizedFormatKey</key>
        <string>%#@count@</string>
        <key>count</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>d</string>
            <key>zero</key>
            <string>No items</string>
            <key>one</key>
            <string>%d item</string>
            <key>other</key>
            <string>%d items</string>
        </dict>
    </dict>
</dict>
</plist>

// Usage in Swift:
String(format: NSLocalizedString("items_count", comment: ""),
       itemCount)
アラビア語には 6 種類、ロシア語には 3 種類、日本語には 1 種類の複数形があります。対象言語で必要となる CLDR カテゴリを必ずすべて定義してください。String Catalog の複数形ビジュアルエディターを使えば、簡単に定義できます。
6

Fastlane で App Store メタデータをローカライズ

Fastlane の deliver ツールを使用すると、App Store のメタデータ(アプリ名、サブタイトル、説明、キーワード、リリースノート)をロケール別のプレーンテキストファイルとしてリポジトリでバージョン管理できます。

Terminal
# Install Fastlane
$ gem install fastlane

# Initialize deliver for App Store metadata
$ fastlane deliver init

# Directory structure created:
# fastlane/metadata/
# ├── en-US/
# │   ├── name.txt            # App name (30 chars)
# │   ├── subtitle.txt        # Subtitle (30 chars)
# │   ├── description.txt     # Full description
# │   ├── keywords.txt        # Search keywords (100 chars)
# │   ├── release_notes.txt   # What's New
# │   └── promotional_text.txt
# ├── de-DE/
# │   └── ...
# └── ja/
#     └── ...

# Push metadata to App Store Connect:
$ fastlane deliver
クロスローカリゼーション:アメリカの App Store では、英語とスペイン語の両方のキーワードがインデックスされます。メタデータをスペイン語にローカライズすると、別の市場を対象にすることなく、アメリカのヒスパニック系ユーザーによる検索にも対応できます。
7

ローカリゼーションをテスト

デバイスの言語を変更せずに、ローカライズ済みコンテンツをテストできます。Xcode スキームのオーバーライドで任意の言語を使用してアプリを実行し、SwiftUI プレビューでは locale 環境、XCUITest の自動テストでは起動引数を使用します。

Testing Localization
// 1. Xcode Scheme Override:
// Edit Scheme > Run > Options > App Language > Choose language

// 2. SwiftUI Preview with locale:
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environment(\.locale, Locale(identifier: "de"))

        ContentView()
            .environment(\.locale, Locale(identifier: "ja"))

        ContentView()
            .environment(\.locale, Locale(identifier: "ar"))
    }
}

// 3. XCUITest with language override:
let app = XCUIApplication()
app.launchArguments += ["-AppleLanguages", "(de)"]
app.launchArguments += ["-AppleLocale", "de_DE"]
app.launch()
ドイツ語(英語より文字列が約 30% 長くなります)と日本語(文字列が約 50% 短くなります)でテストし、レイアウトの問題を早期に検出します。実際の翻訳がなくても、Xcode の疑似ローカリゼーションでレイアウトを厳しく検証できます。

翻訳品質を自動管理

i18n-validate を使用し、キー不足、壊れたプレースホルダー、複数形の問題をリリース前に検出します。実際の翻訳が完成する前に、i18n-pseudo の疑似翻訳で UI をテストできます。
8

翻訳を自動化

AI を使用して、.strings、.xcstrings、Fastlane メタデータファイルを翻訳します。アプリ内文字列と App Store メタデータの両方を自動翻訳し、あらゆる要素をローカライズできます。

Terminal
# Translate .strings files
> Translate Base.lproj/Localizable.strings
  to Japanese, German, and Spanish

# Translate App Store metadata too
> Translate fastlane/metadata/en-US/
  to de-DE, ja, es-MX

✓ 6 files translated in 3.2s
App Store をローカライズすると、英語圏以外の市場でダウンロード数が 30% 以上増加します。アプリ内文字列と同時にメタデータも翻訳してください。最も高い ROI が期待できるローカリゼーション施策です。
+

追加機能:LocaleChain によるスマートなロケールフォールバック

デフォルトの iOS では、ユーザーのロケールに完全一致する翻訳がない場合、開発言語へフォールバックします。pt-PT の翻訳だけがあると、pt-BR のユーザーにはポルトガル語ではなく英語が表示されます。LocaleChain は、設定可能なフォールバックチェーンでこの問題を解決します。

LocaleChain はオープンソースの Swift パッケージです。GitHub で見る

Package Dependencies
// Swift Package Manager
// File > Add Package Dependencies >
// https://github.com/i18n-agent/ios-localechain.git
MyApp.swift
import LocaleChain

// In your App init or AppDelegate:
LocaleChain.configure()  // Activates all default chains

// pt-BR user with only pt-PT translations?
// → Shows Portuguese instead of falling back to English

// Custom overrides for your specific locales:
LocaleChain.configure(
    overrides: ["es-MX": ["es-419", "es"]]
)

よくある落とし穴

.strings ファイルの構文エラー

セミコロン不足、エスケープされていない引用符、不正なエンコーディングが原因で、エラーが表示されないまま失敗します。ファイルは読み込まれても翻訳は空になります。コミット前に、必ず .strings ファイルを検証してください。

SwiftUI の Text 補間がローカライズされない

Text("Hello \(stringVar)") は想定どおりにローカライズされません。計算によって生成する文字列には String(localized:) を使用するか、補間変数が LocalizedStringKey.StringInterpolation に適した型であることを確認してください。

ウィジェットや拡張機能に未処理のキーが表示される

アプリ拡張機能には個別のバンドルがあります。.strings または .xcstrings ファイルが、メインアプリのターゲットだけでなく、拡張機能ターゲットの Copy Bundle Resources フェーズにも追加されていることを確認してください。

本番環境で翻訳のないキーが表示される

ユーザーの言語に対応する翻訳がキーにない場合、iOS はキー自体を表示します。フォールバック言語の仕組みを導入し、リリース前に対応するすべてのロケールをテストしてください。

推奨ファイル構成

Project Structure
MyApp/
├── MyApp.xcodeproj
├── MyApp/
│   ├── Base.lproj/
│   │   ├── Localizable.strings       # Source strings
│   │   └── Localizable.stringsdict   # Plural rules
│   ├── en.lproj/
│   │   └── Localizable.strings
│   ├── de.lproj/
│   │   └── Localizable.strings
│   ├── ja.lproj/
│   │   └── Localizable.strings
│   ├── Localizable.xcstrings          # OR String Catalog
│   └── Info.plist
├── MyAppTests/
├── fastlane/
│   ├── Fastfile
│   └── metadata/
│       ├── en-US/
│       │   ├── name.txt
│       │   ├── description.txt
│       │   └── keywords.txt
│       ├── de-DE/
│       └── ja/
└── Package.swift

i18n Agent を今すぐ試す

翻訳ファイルをここにドロップ

JSON, YAML, PO, XML, CSV, Markdown, Properties

またはクリックしてファイルを選択

翻訳先言語

登録不要すぐに見積もり

ios-localechain によるロケールフォールバック

de-AT のような地域ロケールで翻訳キーが不足している場合、iOS は最初に親ロケールの de を確認せず、開発言語へ直接移ります。

Terminal
// Swift Package Manager
// https://github.com/i18n-agent/ios-localechain
Configuration
import LocaleChain

LocaleChain.configure(overrides: [
    "de": ["en-GB", "en"],
    "pt-BR": ["pt", "en"],
    "zh-Hant-HK": ["zh-Hant", "zh", "en"],
])

対応フレームワークと 75 種類の組み込みチェーンの完全な一覧については、ロケールフォールバックガイドをご覧ください。 Learn more →

iOS ローカリゼーションに関するよくある質問