10

Swift 条件付きコンパイル ステートメントで iOS 展開ターゲットを確認するにはどうすればよいですか?

私は次のことを試しました:

#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
    // some code here
#else
    // other code here
#endif

ただし、最初の式ではコンパイル エラーが発生します。

Expected '&&' or '||' expression
4

5 に答える 5

12

TL;DR? > 3. 解決策へ

1. Swift での前処理

前処理ディレクティブに関するAppleのドキュメントによると:

Swift コンパイラにはプリプロセッサが含まれていません。代わりに、コンパイル時の属性、ビルド構成、および言語機能を利用して、同じ機能を実現します。このため、プリプロセッサ ディレクティブは Swift にインポートされません。

__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0そのため、C のプリプロセス ディレクティブを使用しようとするとエラーが発生します。swift では#if、 などの演算子では使用できません<。あなたができることは次のとおりです。

#if [build configuration]

または条件付き:

#if [build configuration] && ![build configuration]

2. 条件付きコンパイル

再び同じドキュメントから:

ビルド構成には、次の表に示すリテラルの true 値と false 値、コマンド ライン フラグ、およびプラットフォーム テスト関数が含まれます。-D <#flag#> を使用して、コマンド ライン フラグを指定できます。

  • trueandfalse : 役に立たない
  • platform-testing functions :os(iOS)またはarch(arm64)> は役に立たず、少し検索しましたが、それらがどこに定義されているかわかりません。(おそらくコンパイラ自体で?)
  • コマンド ライン フラグ: さぁ、これが使用できる唯一のオプションです...

3. 解決策

少し回避策のように感じますが、仕事はします: その他の Swift フラグ

たとえば、もちろんターゲットが iOS7 であると仮定して、#if iOSVersionMinRequired7代わりに を使用できます。__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0

これは基本的に、プロジェクトで iOS 展開ターゲットのバージョンを変更することと同じですが、便利ではありません... もちろん、iOS バージョンのターゲットに応じて、関連するスキームを使用して複数のビルド構成を行うことができます。

Appleはきっとこれを改善するでしょう、おそらくいくつかの組み込み機能でos()...

于 2014-06-24T22:30:16.077 に答える
7

Swift 2.2 でテスト済み

つまり、またはDeployment Target? 以下に、複数のバージョンのアプリ (無料アプリ、有料アプリなど) があり、異なるアプリ ターゲットを使用する場合のソリューションを提供します。iOS versionApp Target

カスタム ビルド構成を設定できます:
1. プロジェクトに移動 / ターゲットを選択 / ビルド設定 / カスタム フラグを検索
2. 選択したターゲットに対して、Debug と Release 3-Dの両方でプレフィックス (空白なし)を使用してカスタム フラグを設定
あなたが持っているすべてのターゲットに対して上記の手順を実行します

ここに画像の説明を入力

ターゲットを区別するには、次のようにします。

var target: String {
    var _target = ""
    #if BANANA
        _target = "Banana"
    #elseif MELONA
        _target = "Melona"
    #else
        _target = "Kiwi"
    #endif
    return _target
}

override func viewDidLoad() {
    super.viewDidLoad()
    print("Hello, this is target: \(target)"
}
于 2016-04-08T14:37:46.453 に答える
0

そのような条件付きコンパイル ステートメントでは実行できません。Apple が呼ぶ「複雑なマクロ」は、Swift ではサポートされていません。ジェネリックと型は、頭の中で同じことを行い、より良い結果をもたらします。(これは彼らが公開したリンクです https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html#//apple_ref/doc/uid/TP40014216-CH8-XID_13

これは私が思いついた関数で、同じことを実現します(明らかに、文字列の戻り値を、ブール値やオプション自体のような便利なものに置き換えるだけです):

func checkVersion(ref : String) -> String {
    let sys = UIDevice.currentDevice().systemVersion
    switch sys.compare(ref, options: NSStringCompareOptions.NumericSearch, range: nil, locale: nil) {
    case .OrderedAscending:
        return ("\(ref) is greater than \(sys)")
    case .OrderedDescending:
        return ("\(ref) is less than \(sys)")
    case .OrderedSame:
        return ("\(ref) is the same as \(sys)")
    }
}

// Usage
checkVersion("7.0") // Gives "7.0 is less than 8.0"
checkVersion("8.0") // Gives "8.0 is the same as 8.0"
checkVersion("8.2.5") // Gives "8.2.5 is greater than 8.0"
于 2014-06-23T17:47:03.973 に答える
0

ソース コードが異なる機能を持つ複数の iOS および macOS バージョンをサポートするライブラリを構築するときに、最近、この問題に遭遇しました。

私の解決策は、実際の展開ターゲットから値を導出する Xcode でカスタム ビルド フラグを使用することです。

TARGET_IOS_MAJOR = TARGET_IOS_MAJOR_$(IPHONEOS_DEPLOYMENT_TARGET:base)
TARGET_MACOS_MAJOR = TARGET_MACOS_MAJOR_$(MACOSX_DEPLOYMENT_TARGET:base)

Others Swift Flagsでユーザー定義の設定を参照すると、次のようになります。

OTHER_SWIFT_FLAGS = -D$(TARGET_MACOS_MAJOR) -D$(TARGET_IOS_MAJOR)

次のように、Swift ソースで実際のメジャー OS バージョンを確認できます。

#if os(macOS)
    #if TARGET_MACOS_MAJOR_12
        #warning("TARGET_MACOS_MAJOR_12")

    #elseif TARGET_MACOS_MAJOR_11
        // use custom implementation
        #warning("TARGET_MACOS_MAJOR_11")
    #endif

#elseif os(iOS)
    #if TARGET_IOS_MAJOR_15
        #warning("TARGET_IOS_MAJOR_15")

    #elseif TARGET_IOS_MAJOR_14
        #warning("TARGET_IOS_MAJOR_14")

    #else
        #warning("older iOS")
    #endif
#endif

現在、SPM パッケージで同様のアプローチが可能かどうかはわかりません。これは、後の段階でやろうとしていることです。

于 2022-02-13T10:55:40.837 に答える