環境変数:モバイルプロジェクトでの概要、使用方法、設定

著者: IT Sectr 公開日: 2026-05-31 読了時間: 8 分

環境変数は、コードを変更せずに動作を設定するために、アプリケーションの起動時に渡される動的な値です。開発、テスト、本番の設定を分離できます。Twelve-Factor App、2025によると、設定はコードではなく環境変数に保存する必要があります。環境変数は、APIキー、バックエンドURL、フィーチャーフラグの安全な管理を保証します。

重要ポイント

  • 環境変数は、異なる実行環境向けにアプリケーション設定をソースコードから分離します
  • .envファイルはKEY=VALUE形式で変数を保存し、.gitignoreを介してリポジトリから除外されます
  • iOSはxcconfigとBuild Settingsを使用してコンパイル時に変数を渡します
  • AndroidはBuildConfigとgradle.propertiesを使用して設定フィールドを生成します
  • セキュリティ:キーとトークンはCI/CDを介してロードし、コードやリポジトリに保存しないでください

環境変数とは

環境変数は、オペレーティングシステムのAPIを介してアプリケーションプロセスがアクセスできるキーと値のペアです。プロセスの作成時に渡され、実行中のみ存在します。ソースコードに埋め込まれた設定パラメーターとは異なり、環境変数は値を変更するために再コンパイルを必要としません。これはTwelve-Factor Appの基本原則であり、コードと設定の明確な分離を保証します。

モバイル開発では、環境変数は異なる環境向けの設定の問題を解決します。開発者はローカルサーバーを、テスターはステージングを、ユーザーは本番を使用します。コード内でif-else条件文とともに3つのバックエンドURLを保存する代わりに、開発者はビルド時に環境変数を介して1つのURLを渡します。これによりコードが簡素化され、テスト環境で誤って本番サーバーを使用するリスクが排除されます。

主な利点はセキュリティです。機密データがコードリポジトリに漏れることはありません。APIキー、Firebaseシークレット、バックエンドアクセストークン、証明書はCI/CDを介してビルド環境に直接ロードされます。攻撃者がコードリポジトリにアクセスしても、シークレットはCIシステムの保護されたストレージに保存され、バイナリファイルのビルド段階でのみ渡されるため、見つけることはできません。

モバイル開発で環境変数が必要な理由

モバイルプロジェクトには少なくとも3つの環境があります。開発、ステージング、本番です。各環境には独自の設定セットが必要です:サーバーURL、パッケージ名、署名スキーム、プッシュ通知証明書。環境変数がない場合、開発者はビルドごとに手動で設定を変更する必要があり、エラーの原因になります。テストビルドで本番キーを忘れると、実際のユーザーに通知が送信されたり、有料APIが消費されたりする可能性があります。

環境の分離

環境変数を使用すると、コードを変更せずにバックエンドを切り替えられます。API_BASE_URL変数の値を変更するだけです。フィーチャーフラグはFEATURE_CHAT_ENABLED=trueのような変数で管理され、本番に影響を与えずにステージングで新機能を有効にできます。各環境には独自の.envファイルがあり、ビルド時にロードされます。

dart
class AppConfig {
  static final String apiBaseUrl =
    const String.fromEnvironment('API_BASE_URL',
      defaultValue: 'http://localhost:8080');
}

キーのセキュリティ

ハードコードされたキーはモバイルアプリケーションの一般的な脆弱性です。攻撃者はjadxやHopperなどのツールを使用してAPKまたはIPAを逆コンパイルし、バイナリファイルからシークレットを抽出します。難読化でさえ文字列リテラルを保護できません。逆コンパイル後にコード内で簡単に見つかります。環境変数は、CI/CDを介してビルド時にキーを渡すことでこの問題を解決し、ログでマスクされます。

kotlin
object Config {
    val apiKey: String =
        System.getenv("API_KEY") ?: throw
            IllegalStateException("API_KEY not set")
}

CI/CD統合

環境変数はビルドパイプラインと統合されます。GitHub Actions、GitLab CI、Bitrise、CircleCIは、ログに表示されないシークレット変数をサポートしています。ビルド時に、CIはブランチまたはタグに応じて適切な値を代入します。developブランチにはステージング、v*タグには本番が使用されます。これによりプロセスが自動化され、人的要因が排除され、各ビルドが正しい設定セットを受け取ることが保証されます。

.envファイルと管理ライブラリ

.envファイルは、KEY=VALUE形式で環境変数を保存する標準的な方法です。リポジトリには含まれず、代わりにすべての変数のテンプレートと空の値を含む.env.exampleが追加されます。各開発者は、チームメンバーの設定に影響を与えずに、ローカル設定を含む独自の.envファイルを作成します。異なる環境には別々のファイルが使用されます:.env.dev、.env.stage、.env.prod。

bash
# .env.example — 開発者向けテンプレート
API_BASE_URL=http://localhost:8080
FEATURE_CHAT_ENABLED=true
SENTRY_DSN=

モバイルプロジェクト向けには、.envファイルを操作するための専門のライブラリがあります:

  • flutter_dotenv(Flutter)— dotenv.load()を介して実行時に.envから変数をロード
  • BuildConfig(Android)— build.gradleの値から型付きフィールドを生成
  • xcconfig(iOS)— 異なるXcodeビルドスキームに設定ファイルを接続
  • react-native-config(React Native)— .envファイルを介した変数管理

CI/CDのブランチ設定により、異なる.envファイルを代入できます:テストサーバー用に.env.dev、プレリリース用に.env.stage、アプリストア公開用に.env.prod。シークレットを含むファイルは安全なストレージ(Vault、AWS Secrets Manager)からロードされ、リポジトリには保存されません。これにより、バージョン管理システムが侵害されても、シークレットは保護されたままになります。

iOSプロジェクトの環境変数

iOSエコシステムは、ビルドレベルで変数を管理するためにxcconfigファイルを使用します。これらはXcodeスキームに接続され、DebugおよびRelease設定の値をオーバーライドできます。xcconfigファイルは継承をサポートしており、共通設定を含むベースファイルと、各環境用の固有ファイルを作成できます。

xcconfigファイルの設定

xcconfigファイルはKEY = VALUE形式で変数を保存し、Configuration設定を介してXcodeのビルドスキームに接続されます。xcconfigの変数は$(VARIABLE_NAME)構文を介してInfo.plistで利用可能になり、異なるスキームに異なるバンドル識別子とアプリ名を使用できます。環境をすばやく識別するために、アプリ名にDevまたはStagingの接尾辞が追加されます。

bash
# Config/Dev.xcconfig — 開発設定
API_BASE_URL = http://localhost:3000
BUNDLE_ID_SUFFIX = .dev
APP_DISPLAY_NAME = MyApp Dev

変数を読み取るSwiftコード

iOSで実行時に変数にアクセスするには、Configuration.swiftファイルを使用し、Bundle.main.object(forInfoDictionaryKey:)を介してInfo.plistから値を読み取ります。このアプローチにより、変数がビルド時に定義され、起動直後にアプリケーションが利用できることが保証されます。値はモジュールの初期化時に1回読み取られ、アプリケーションのライフサイクル全体で高速アクセスするためにキャッシュされます。

swift
enum AppEnvironment {
    static var apiBaseURL: URL {
        guard let urlString = Bundle.main
            .object(forInfoDictionaryKey: "API_BASE_URL"),
              let url = URL(string: urlString as! String)
        else { fatalError("API_BASE_URL is not configured") }
        return url
    }

    static var isChatEnabled: Bool {
        Bundle.main.object(
            forInfoDictionaryKey: "FEATURE_CHAT_ENABLED"
        ) as? Bool ?? false
    }
}

Androidプロジェクトの環境変数

AndroidはBuildConfigを介して環境変数をサポートします。これは自動生成されるクラスで、そのフィールドはモジュールのbuild.gradleファイルで定義されます。BuildConfigはコンパイル時にフレーバーとビルドタイプごとに個別に作成されます。これにより、コードで条件演算子を使用せずにデバッグとリリースで異なる値を設定でき、パフォーマンスとセキュリティが向上します。

BuildConfigフィールドの設定

BuildConfigフィールドは、defaultConfigまたは特定のbuildTypesでbuildConfigFieldを介して設定されます。各環境に個別のbuildTypeまたはproductFlavorが作成されます。これにより、設定の厳格な分離が保証されます。デバッグはローカルサーバー、リリースは本番を使用します。BuildConfigフィールドは静的に型付けされているため、コードでアクセスする際のエラーが排除されます。

groovy
// build.gradle (Module: app)
android {
    defaultConfig {
        buildConfigField "String", "API_BASE_URL",
            "\"http://localhost:8080\""
    }
    buildTypes {
        debug {
            buildConfigField "String", "API_BASE_URL",
                "\"http://dev.api.itsectr.com\""
        }
        release {
            buildConfigField "String", "API_BASE_URL",
                "\"https://api.itsectr.com\""
        }
    }
}

共有値のためのgradle.properties

プロジェクトルートのgradle.propertiesファイルは、グローバルなGradle変数を保存します。これらは$variableName構文を介してすべてのモジュールで利用可能で、依存関係のバージョン、ビルドフラグ、APIキーの指定に使用されます。BuildConfigとは異なり、gradle.propertiesはGradle設定段階でのみ機能し、アプリケーションの実行時には機能しません。したがって、gradle.propertiesで指定されたパスワードとAPIキーは逆コンパイルされたコードで表示されません。コンパイル時にBuildConfigを生成するためだけに使用されるからです。

groovy
# gradle.properties
SENTRY_DSN=https://key@sentry.io/project
MAPS_API_KEY=AIzaSy...

Androidプロジェクトでシークレットを安全に転送するには、local.properties(VCSから除外)を使用するか、System.getenv()を介してbuild.gradleのCI/CD変数から値をロードすることをお勧めします。これにより、キーがリポジトリに漏れることがなくなります。Google Play Consoleに公開する際は、すべてのデバッグキーが、対応するBuildConfig値を持つ異なるbuildTypesまたはproductFlavorsを介して本番バージョンに置き換えられていることを確認してください。

よくある質問

Flutterで環境変数を使用できますか?

はい、Flutterは実行時アクセス用のflutter_dotenvパッケージ、またはプラットフォーム変数用のネイティブチャネルを介して環境変数をサポートしています。Dartには、--dart-defineを介してコンパイル時に値を渡すためのString.fromEnvironmentコンストラクターもあり、Flutterプロジェクトではこちらが推奨される方法です。

BuildConfigとgradle.propertiesの違いは何ですか?

BuildConfigは、各buildTypeとflavorのコンパイル時に生成される型付きフィールドを持つJavaクラスです。gradle.propertiesは、ビルド設定段階ですべてのGradleモジュールがアクセスできるキーと値のペアを含むテキストファイルです。BuildConfigはアプリケーションの実行時に機能し、gradle.propertiesはGradleスクリプト内でのみ機能します。

.envファイルがリポジトリに漏れるのを防ぐには?

リポジトリの.gitignoreファイルに.envを追加します。リポジトリには、空の値と各変数の説明を含む.env.exampleのみをコミットします。CI/CDには、GitHub Actions、GitLab CI、またはBitriseの設定で暗号化されたシークレットを使用します。これらはログでマスクされ、ビルド完了後に読み取ることはできません。

CI/CDを介して環境変数を渡すには?

ほとんどのCIシステムはシークレット環境変数をサポートしています。GitHub ActionsではSecrets、GitLab CIではCI/CD Variables、BitriseではSecretsです。ビルド時に、process.envまたはSystem.getenv()を介してビルドスクリプトに渡されます。シークレット変数はビルドログに表示されず、リポジトリのフォークでは利用できません。

環境変数によるフィーチャーフラグとは?

フィーチャーフラグは、コードを再コンパイルせずに機能の有効化または無効化を制御するブール変数です。例:FEATURE_NEW_PAYMENT=trueで、テスト用にステージングで新しい支払いシステムを有効にします。本番では、バックエンドが完全にデプロイされるまで同じフラグはfalseに設定されます。これにより、変更を段階的に安全にロールアウトし、問題が発生した場合にロールバックできます。

まとめ

  • 環境変数は、異なる開発環境向けに設定をソースコードから分離します
  • .envファイルと.env.exampleテンプレートは、環境分離のあるチームでの変数管理の標準です
  • iOS xcconfigは、継承サポートとInfo.plist統合により設定ファイルをXcodeスキームに接続します
  • Android BuildConfigは、buildTypeごとにbuild.gradleから型付きフィールドを個別に生成します
  • CI/CDシークレットは、リポジトリに保存せずにビルド時に機密データを渡します
  • フィーチャーフラグは変数を介して、再コンパイルなしで特定の環境で機能を有効にできます
  • セキュリティ:キーはCIで暗号化され、アプリケーションの逆コンパイル可能なバイナリファイルに漏れることはありません

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください