Objective-Cでは、マクロを使用してデバイスまたはシミュレーター向けにアプリが構築されているかどうかを確認できます。
#if TARGET_IPHONE_SIMULATOR
    // Simulator
#else
    // Device
#endifこれらはコンパイル時マクロであり、実行時には使用できません。
Swiftで同じことをするにはどうすればよいですか?
Objective-Cでは、マクロを使用してデバイスまたはシミュレーター向けにアプリが構築されているかどうかを確認できます。
#if TARGET_IPHONE_SIMULATOR
    // Simulator
#else
    // Device
#endifこれらはコンパイル時マクロであり、実行時には使用できません。
Swiftで同じことをするにはどうすればよいですか?
回答:
この答えはうまくいくかもしれませんが、静的チェックの推奨される解決策(いくつかのAppleエンジニアによって明らかにされています)は、iOSシミュレータをターゲットとするカスタムコンパイラフラグを定義することです。それを行う方法の詳細な手順については、@ mbelskyの回答を参照してください。
静的チェックが必要な場合(ランタイムのif / elseなどではない)、シミュレータを直接検出することはできませんが、次のようにデスクトップアーキテクチャでiOSを検出できます。
#if (arch(i386) || arch(x86_64)) && os(iOS)
    ...
#endifSwift 4.1バージョン以降
すべてのタイプのシミュレーターが1つの条件のみを適用する必要があるため、最新の使用法がオールインワン条件に直接適用されます-
#if targetEnvironment(simulator)
  // your simulator code
#else
  // your real device code
#endif詳細については、Swiftの提案SE-0190を確認してください。
古いバージョンの場合 -
明らかに、これはデバイスではfalseですが、ドキュメントで指定されているように、iOSシミュレーターではtrueを返します。
コードが32ビットiOSシミュレーター用にコンパイルされると、arch(i386)ビルド構成はtrueを返します。
iOS以外のシミュレータ用に開発している場合は、osパラメータを変更するだけです。例:
watchOSシミュレーターを検出する
#if (arch(i386) || arch(x86_64)) && os(watchOS)
...
#endiftvOSシミュレーターを検出する
#if (arch(i386) || arch(x86_64)) && os(tvOS)
...
#endifまたは、でも、検出任意のシミュレータを
#if (arch(i386) || arch(x86_64)) && (os(iOS) || os(watchOS) || os(tvOS))
...
#endif代わりにランタイムチェックで問題がなければ、TARGET_OS_SIMULATOR変数(またはTARGET_IPHONE_SIMULATORiOS 8以下)を検査できます。これはシミュレーターで真実です。
これはプリプロセッサフラグを使用する場合とは異なり、多少制限があることに注意してください。たとえば、a if/elseが構文的に無効な場所(たとえば関数スコープの外)で使用することはできません。
たとえば、デバイスとシミュレータに異なるインポートを設定するとします。これは、動的チェックでは不可能ですが、静的チェックでは簡単です。
#if (arch(i386) || arch(x86_64)) && os(iOS)
  import Foo
#else
  import Bar
#endifまた、フラグはSwiftプリプロセッサによってa 0またはaに置き換えられるため、式1で直接使用するとif/else、コンパイラは到達不能コードに関する警告を表示します。
この警告を回避するには、他の回答のいずれかを参照してください。
#if targetEnvironment(simulator):)(github.com/apple/swift-evolution/blob/master/proposals/...)
                    SWIFT 4.1より古い。#if targetEnvironment(simulator)代わりに使用してください。ソース
Swiftでシミュレーターを検出するには、ビルド構成を使用できます。
これで、このステートメントを使用してシミュレーターを検出できます。
#if IOS_SIMULATOR
    print("It's an iOS Simulator")
#else
    print("It's a device")
#endifまた、UIDeviceクラスを拡張することもできます。
extension UIDevice {
    var isSimulator: Bool {
        #if IOS_SIMULATOR
            return true
        #else
            return false
        #endif
    }
}
// Example of usage: UIDevice.current.isSimulatorxcconfig使用してファイルOTHER_SWIFT_FLAGS = TARGET_OS_EMBEDDEDとOTHER_SWIFT_FLAGS[sdk=embeddedsimulator*] = TARGET_OS_SIMULATORシミュレータのために上書きします。
                    2018年2月20日現在の更新された情報
@russbishopには信頼できる回答があり、この回答が「正しくない」ように見えます-長期間動作しているように見えましたが。
Swiftでデバイスまたはシミュレーター用にアプリがビルドされているかどうかを検出する
前の回答
@WZWの回答と@Pangのコメントに基づいて、簡単なユーティリティ構造体を作成しました。このソリューションは、@ WZWの回答によって生成される警告を回避します。
import Foundation
struct Platform {
    static var isSimulator: Bool {
        return TARGET_OS_SIMULATOR != 0
    }
}使用例:
if Platform.isSimulator {
    print("Running on Simulator")
}public let IS_SIMULATOR = (TARGET_OS_SIMULATOR != 0)。+1感謝
                    TARGET_OS_SIMULATOR != 0はすでに回答に含まれています。それはダニエルによって与えられた解決策です。自由変数に再度追加する必要はありません。すでに存在しています。構造体でそれを使用するのが悪いと思い、自由変数で使用する方が良い場合は、これについてコメントを投稿するか、自分で答えてください。ありがとう。
                    Xcode 9.3以降
#if targetEnvironment(simulator)Swiftは、単一の有効な引数シミュレータを備えた新しいプラットフォーム条件targetEnvironmentをサポートします。'#if targetEnvironment(simulator)'形式の条件付きコンパイルを使用して、ビルドターゲットがシミュレーターであることを検出できるようになりました。Swiftコンパイラーは、既存のos()およびarch()プラットフォーム条件を介して間接的にシミュレーター環境をテストしているように見えるプラットフォーム条件を評価するときに、targetEnvironment(simulator)の使用を検出、警告、および提案しようとします。(SE-0190)
iOS 9以降:
extension UIDevice {
    static var isSimulator: Bool {
        return NSProcessInfo.processInfo().environment["SIMULATOR_DEVICE_NAME"] != nil
    }
}スウィフト3:
extension UIDevice {
    static var isSimulator: Bool {
        return ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil
    }
}iOS 9より前:
extension UIDevice {
    static var isSimulator: Bool {
        return UIDevice.currentDevice().model == "iPhone Simulator"
    }
}Objective-C:
@interface UIDevice (Additions)
- (BOOL)isSimulator;
@end
@implementation UIDevice (Additions)
- (BOOL)isSimulator {
    if([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){9, 0, 0}]) {
        return [NSProcessInfo processInfo].environment[@"SIMULATOR_DEVICE_NAME"] != nil;
    } else {
        return [[self model] isEqualToString:@"iPhone Simulator"];
    }
}
@endwill never be executed警告を出さない
                    targetEnvironment(simulator)これで引数として使用できます。
#if targetEnvironment(simulator)
    // Simulator
#else
    // Device
#endifXcode 9.3用に更新
ここでいくつかのことを明確にしましょう:
TARGET_OS_SIMULATOR多くの場合、Swiftコードでは設定されません。ブリッジングヘッダーが原因で誤ってインポートされる可能性がありますが、これは脆弱であり、サポートされていません。また、フレームワークでは不可能です。これが、これがSwiftで機能するかどうか混乱している理由です。動的チェックを実行するには:
チェックProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nilは完全に問題ありません。
また、のSIMULATOR_MODEL_IDENTIFIERような文字列を返すかどうかを確認することで、シミュレーションされる基になるモデルを取得することもできますiPhone10,3。
静的チェックを実行するには:
Xcode 9.2以前:独自のSwiftコンパイルフラグを定義します(他の回答に示されています)。
Xcode 9.3以降では、新しいtargetEnvironment条件を使用します。
#if targetEnvironment(simulator)
    // for sim only
#else
    // for device
#endiftargetEnvironmentはXcode 9.3に導入されました。新しいバージョンのXcodeが必要です。
                    ランタイムですが、ここにある他のほとんどのソリューションよりも単純です。
if TARGET_OS_SIMULATOR != 0 {
    // target is current running in the simulator
}または、プリプロセッサマクロを使用するブール値を返すObjective-Cヘルパー関数を呼び出すだけでもかまいません(特に、プロジェクトで既に混合している場合)。
編集:特にXcode 9.3の時点では、最善の解決策ではありません。HotJardの回答を見る
== 0代わりに使用したときにのみ警告が表示されます!= 0。上記のようにそれを使用したelse後、ブロックを続けても、Swift 4 Xcodeバージョン9.2(9C40b)で警告は生成されません
                    TARGET_IPHONE_SIMULATORiOS 9では非推奨ですTARGET_OS_SIMULATOR。代わりに またTARGET_OS_EMBEDDED利用できます。
TargetConditionals.hから:
#if defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__) ) . . . #define TARGET_OS_SIMULATOR 0 #define TARGET_OS_EMBEDDED 1 #define TARGET_IPHONE_SIMULATOR TARGET_OS_SIMULATOR /* deprecated */ #define TARGET_OS_NANO TARGET_OS_WATCH /* deprecated */
この拡張機能がお役に立てば幸いです。
extension UIDevice {
    static var isSimulator: Bool = {
        #if targetEnvironment(simulator)
        return true
        #else
        return false
        #endif
    }()
}使用法:
if UIDevice.isSimulator {
    print("running on simulator")
}Xcode 7.2(およびそれ以前のバージョンではテストしていません)では、「Any iOS Simulator」に対してプラットフォーム固有のビルドフラグ「-D TARGET_IPHONE_SIMULATOR」を設定できます。
「Swift Compiler-Customer Flags」のプロジェクトビルド設定を確認し、「Other Swift Flags」でフラグを設定します。ビルド構成にカーソルを合わせたときに「プラス」アイコンをクリックすると、プラットフォーム固有のフラグを設定できます。
このようにすることにはいくつかの利点があります。1)SwiftとObjective-Cのコードで同じ条件テスト( "#if TARGET_IPHONE_SIMULATOR")を使用できます。2)各ビルドにのみ適用される変数をコンパイルできます。
ここですべて説明Darwin.TargetConditionals:https : //github.com/apple/swift-corelibs-foundation/blob/master/CoreFoundation/Base.subproj/SwiftRuntime/TargetConditionals.h
TARGET_OS_SIMULATOR - Generated code will run under a simulator
私はSwift 3で以下のコードを使用しました
if TARGET_IPHONE_SIMULATOR == 1 {
    //simulator
} else {
    //device
}現在、ProcessInfoクラスを使用して、デバイスがシミュレータであるかどうか、およびどの種類のデバイスが使用されているかを確認します。
if let simModelCode = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
            print("yes is a simulator :\(simModelCode)")
}しかし、ご存じのように、simModelCodeどの種類のシミュレーターが起動されたかをすぐに理解するのに適したコードではないので、必要に応じて、この別のSOの答えを見て、現在のiPhone /デバイスモデルを特定し、より人間的なものにすることができます。読み取り可能な文字列。
上記のHotJardの素晴らしい答えに基づいたXcode 11 Swiftの例を次に示します。これにより、isDeviceBoolが追加され、SIMULATOR_UDID名前の代わりに使用されます。変数の割り当ては各行で行われるため、必要に応じてデバッガーで変数の割り当てを簡単に調べることができます。
import Foundation
// Extensions to UIDevice based on ProcessInfo.processInfo.environment keys
// to determine if the app is running on an actual device or the Simulator.
@objc extension UIDevice {
    static var isSimulator: Bool {
        let environment = ProcessInfo.processInfo.environment
        let isSimulator = environment["SIMULATOR_UDID"] != nil
        return isSimulator
    }
    static var isDevice: Bool {
        let environment = ProcessInfo.processInfo.environment
        let isDevice = environment["SIMULATOR_UDID"] == nil
        return isDevice
    }
}DTPlatformNameを含む必要がある辞書エントリもありますsimulator。
以下のコードを使用してください:
#if targetEnvironment(simulator)
   // Simulator
#else
   // Device
#endif以下のための作品Swift 4とXcode 9.4.1
Xcode 11、Swift 5
    #if !targetEnvironment(macCatalyst)
    #if targetEnvironment(simulator)
        true
    #else
        false        
    #endif
    #endif