プリプロセッサマクロがない場合、Xcodeプロジェクトのプロジェクトレベルで実用的なスキーム固有のフラグを定義する方法はありますか


174

早速、私はアルファ、ベータ、およびディストリビューションのビルド用の一連のスキームを定義しました。これらの各スキームには、プロジェクトレベルで特定の動作を制御するために定義された一連のマクロがあります。最も単純な例は、実行ビルドのデフォルトスキームのすべてのXcodeプロジェクトに対してデフォルトで定義されるDEBUG = 1マクロです。#ifdef DEBUG ...をクエリし、それに応じてコードで決定を下し、不要なコードをコンパイルすることもできます。

マクロがサポートされていないため、このタイプの構成ゲーティングは、swiftを使用するほど簡単ではないようです。誰かが同等のアプローチを提案できますか?コード自体がコンパイルされているかどうかは気にしません。ただし、ビルドスキームに基づいて機能をゲートしたいと思います。

回答:


468

Swiftでは、Appleのドキュメントに従って、「#if /#else /#endif」プリプロセッサマクロを使用できます(ただし、より制約されます)。次に例を示します。

#if DEBUG
    let a = 2
#else
    let a = 3
#endif

ただし、「デバッグ」シンボルを他の場所に設定する必要があります。[Swift Compiler-Custom Flags]セクションの[Other Swift Flags]行で設定します。-D DEBUGエントリと共にDEBUGシンボルを追加します。

(ビルド設定-> Swiftコンパイラ-カスタムフラグ) ここに画像の説明を入力してください

通常どおり、デバッグ時またはリリース時に別の値を設定できます。

実際のコードでテストしました。遊び場では認識されていないようです。


5
#elseif行を使用してテストを追加することもできます。興味深いことに、定義にアクセスできますが、そこから何も抽出できません。つまり、-DDEBUG = 5(または= "FOO")を定義してから、「println(DEBUG is(DEBUG)」」を使用して印刷してみます。この行はエラーを生成しませんが、何もしません
David H

10
注:「基本設定」ビルド設定では、「ビルド設定-> Swiftコンパイラ->カスタムフラグ」は表示されません。表示するには、「すべて」のビルド設定を表示する必要があります。
レビボスティアン

7
@EugeneDubinin $(inherited)は、プロジェクト設定を継承するためにターゲット設定で使用されることを確認する必要があるためと考えられます。
DanSkeel

2
@DanSkeel nice catch、追加$(inherited)すると私のコメントは無関係になります。ありがとうございます!
Yevhen Dubinin 2015

10
Xcode 8では、「Swift Compiler-Custom Flags」セクションに「Active Compilation Conditions」設定もあります。-Dを必要とせずにここにフラグを追加できます
Marcus

32

迅速なコンパイラフラグを設定したくないという問題に遭遇しました。それらを設定し、さまざまなターゲットなどで最新に保つ必要がないためです。また、混合コードベースでは、覚えておきたくありませんでした。各言語で常に適切にフラグを設定します。

私たちのために、ObjCでファイルを宣言しました

PreProcessorMacros.h

extern BOOL const DEBUG_BUILD;

.m

PreProcessorMacros.m

#ifdef DEBUG
    BOOL const DEBUG_BUILD = YES;
#else
    BOOL const DEBUG_BUILD = NO;
#endif

次に、Objective-Cブリッジヘッダーで

#import "PreProcessorMacros.h"

これをSwiftコードベースで使用します

if DEBUG_BUILD {
    println("debug")
} else {
    println("release")
}

これは間違いなく回避策ですが、問題は解決したので、役立つことを期待してここに投稿しました。既存の回答が無効であることを示唆するものではありません。


11
マクロの要点は、ビルド構成に基づいてコードを変更することです。ifをランタイムに戻しているので、そのためのマクロは必要ありません。
Berik

18
@Berik-特に他の言語のプロジェクトで、この問題のある側面を解決しようとしている他の人にも役立つことを期待して、有効な解決策を投稿しました。問題が特定のコードをコンパイルする必要がない場合は問題ありません。また、特にこれが彼らのための解決策ではないかもしれない理由をいくつか教育している場合は特に、コメントは問題ありません。また、このアプローチの制限についての回答を書き留めるよう求めます。反対投票は不要であり、同様の問題を解決する他の人に役立つ可能性のある代替ソリューションを推奨しません。また、opは「コードがコンパイルされたかどうかは関係ない」と言っています。
ローガン

5

Logansメソッドのより迅速なソリューション。設定-D DEBUGしてOther Swift FlagsSwift Compiler - Custom Flagsあなたのターゲットのビルド設定にセクション。

次に、次のメソッドをグローバルスコープで宣言します。

#if DEBUG
let isDebugMode = true
#else
let isDebugMode = false
#endif

今それを

if isDebugMode {
    // Do debug stuff
}

1

私にとっては、「Active Compilation Condition」のデバッグ項目を「DEBUG」に設定してみました。

次に、#IFでDEBGUキーを使用すると、デバッグモードでDEBUGが機能し、リリースモードで#ELSEが機能します。

  1. ターゲットを選択し、
  2. 「ビルド設定」タブで「アクティブなコンパイル条件」を検索し、
  3. 「Debug」アイテムの値を「YourKeyWord」に設定し、
  4. 単に次のように使用します:

    #if DEBUG
        print("You'r running in DEBUG mode!")
    #else
        print("You'r running in RELEASE mode!")
    #endif

0

私はobj-cコードがマクロを使用してコンソールにデバッグメッセージを送信する混合言語コードベースで作業しています(そのマクロはデバッグプリプロセッサフ​​ラグに依存しています)。私は迅速なコードで同じマクロを呼び出せるようにしたかった...

  1. そのマクロのラッパーであるobj-cクラスの1つにクラスメソッドを作成しました。
  2. そのobj-cヘッダーをブリッジヘッダーファイルに追加しました。
  3. ここで、私の迅速なコードは、そのクラスメソッドをobj-cマクロへの「プロキシ」として呼び出します。

迅速なコードでマクロを直接呼び出すことができないのは少し厄介なことですが、少なくとも、プロジェクトでデバッグフラグのオン/オフを心配する場所が1つしかないのです。

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