Swift:プリプロセッサフ​​ラグ( `#if DEBUG`など)を使用してAPIキーを実装する方法は?


95

Objective-C、(MixPanel、フラリー又はCrashlyticsように、分析パッケージをRELEASEとデバッグキーを区別するために、例えば)代替APIキーを定義する静的文字列定数を使用することが時には有用でした。

#if DEBUG
static NSString *const API_KEY = @"KEY_A";
#else
static NSString *const API_KEY = @"KEY_B";
#endif

その後...

[Analytics startSession:API_KEY];

Swiftコンパイラはプリプロセッサを使用しなくなったため、これはどのようにSwiftに変換されますか?

回答:


161

AppleはXcode8の時点でSwiftプリプロセッサフ​​ラグの完全なサポートを含んでいたので、「その他のSwiftフラグ」でこれらの値を設定する必要はなくなりました。

新しい設定は「アクティブコンパイル条件」と呼ばれ、プリプロセッサフ​​ラグに相当するSwiftのトップレベルのサポートを提供します。「その他のSwiftフラグ」とまったく同じ方法で使用しますが、値の前に「-D」を付ける必要がない点が異なります(したがって、少しきれいになります)。

Xcodeの8のリリースノート

Active Compilation Conditionsは、条件付きコンパイルフラグをSwiftコンパイラに渡すための新しいビルド設定です。この設定の値の各要素は、接頭辞-Dが付いたswiftcにPreprocessor Macros渡されます。これは、接頭辞が同じclangに渡される要素と同じ方法です。(22457329)

ここに画像の説明を入力してください

上記の設定を次のように使用します。

#if DEBUG
    let accessToken = "DebugAccessToken"
#else
    let accessToken = "ProductionAccessToken"
#endif

2
注:= 1またはその他の=値を指定しないでください。むしろ、フラグ名を指定するだけです。:]
JRG-開発者

@ JRG-開発者私は同意しませんが、あなたのコメントがここでどのように適用されるかはわかりません。
DanLoewenherz19年

9
これは有用な答えですが、Objective-Cのバックグラウンドから来ているので(多くのiOS開発者がそうだと思います)、指定する必要があると思いました=1...なぜそれが機能しなかったのかを理解しようとして少し時間を失いました私がやったとき。それで、私は次の仲間を助けるためにこの一口を共有したいと思いました。:]とにかく、ここであなたの答えをありがとう!
JRG-開発者

1
@ JRGを-開発、@Dan Loewenherz私は両方を設定しているDEBUGActive Compilation ConditionsしてDEBUG=1Preprocessor Macros、この設定は、すべてでは動作しません。削除する必要がありますDEBUG=1か?上記のコメントからは明らかではありません。
Bhavin_m

2
@DanLoewenherzあなたは絶対に正しいです。ターゲット設定でアーカイブ構成に「DEBUG」を設定したので、Debugステートメントを実行するたびに、リリース条件を実行することはありません。問題に直面している人は、Build Configuration最初にターゲットを確認してください。詳細については、この回答stackoverflow.com/questions/9063100/…を確認してください。
Bhavin_m

131

更新:Xcode8はこれを自動的にサポートするようになりました。上記の@DanLoewenherzの応答を参照してください。

Xcode 8より前でも、同じ方法でマクロを使用できました。

#if DEBUG
let apiKey = "KEY_A"
#else
let apiKey = "KEY_B"
#endif

ただし、Swiftがそれらを取得するには、ターゲットのビルド設定で「その他のSwiftフラグ」を設定する必要があります。

  • ターゲットのビルド設定を開きます
  • 「その他の迅速なフラグ」を検索する
  • 使用するマクロを-Dフラグの前に追加します

ここに画像の説明を入力してください


あなたは私の日を作りました!私にとっては-Dプレフィックスなしでは機能しませんでした
nomnom

5

フォローアップの観察として、リポジトリにAPIキー/シークレットをプレーンテキストで保持しないようにしてください。シークレット管理システムを使用して、キー/シークレットをユーザーの環境変数にロードします。それ以外の場合は、許容できる場合はステップ1が必要です。

  1. 囲んでいるリポジトリの上記のプレーンテキストファイルに「秘密」を入れてください
  2. ../set_keys.shリストを含むを作成しますexport API_KEY_A='<plaintext_key_aef94c5l6>'(評価を防ぐために一重引用符を使用します)
  3. 実行可能なスクリプトフェーズを追加し、source ../set_keys.sh実行順序の最上位に移動します
  4. [ビルド設定]> [プリプロセッサマクロ]で、必要に応じて次のような定義に追加します。 API_KEY_A="$API_KEY_A"

これにより、環境変数がコンパイラ定義に取り込まれ、後で各ソースファイルの各clang呼び出しで使用されます。

ディレクトリ構造の例

[10:33:15] ~/code/memo yes? tree -L 2 .
.
├── Memo
│   ├── Memo
│   ├── Memo.xcodeproj
│   ├── Memo.xcworkspace
│   ├── Podfile
│   ├── Podfile.lock
│   └── Pods
└── keys

0

迅速なパッケージでは、ファイル内のswiftSettings引数の中でこれを行う必要があります。メソッド(Appleのドキュメント)またはSwiftのドキュメントを使用します.targetPackage.swiftdefine

targets: [
.target(name: String,
            dependencies: [Target.Dependency],
            path: String?,
            exclude: [String]?,
            sources: [String]?,,
            cSettings: [CSetting]?,
            cxxSettings: [CXXSetting]?,
            swiftSettings: [SwiftSetting]?,
            linkerSettings: [LinkerSetting]?),

鉱山はこのように見え、それは機能します!

            swiftSettings: [
               .define("VAPOR")
            ]

私のコードでは、これを使用して条件付きでコンパイルできます。

#if VAPOR
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.