Swiftでアプリがデバイス用かシミュレータ用かを検出する方法 質問する

Swiftでアプリがデバイス用かシミュレータ用かを検出する方法 質問する

非常に古い歴史的な QA であることに注意してください。

(現在は です #if targetEnvironment(simulator)。)


Objective-C では、マクロを使用して、アプリがデバイス用かシミュレータ用かを知ることができます。

#if TARGET_IPHONE_SIMULATOR
    // Simulator
#else
    // Device
#endif

これらはコンパイル時のマクロであり、実行時には使用できません。

Swift で同じことを実現するにはどうすればよいでしょうか?

ベストアンサー1

2019年1月30日更新

この回答はうまくいくかもしれませんが、静的チェックの推奨される解決策は(複数のAppleエンジニアによって明らかにされているように)iOSシミュレータをターゲットとするカスタムコンパイラフラグを定義することです。その方法の詳細な手順については、@mbelsky の回答

元の回答

静的チェック(例:実行時のif/elseではない)が必要な場合、シミュレータを直接検出することはできませんが、次のようにデスクトップアーキテクチャ上のiOSを検出することができます。

#if (arch(i386) || arch(x86_64)) && os(iOS)
    ...
#endif

Swift 4.1バージョン以降

最新の使用法では、すべてのタイプのシミュレータに1つの条件を直接適用するだけで済みます。

#if targetEnvironment(simulator)
  // your simulator code
#else
  // your real device code
#endif

より詳しい説明については、 Swiftの提案をご覧ください。SE-0190


旧バージョンの場合-

明らかに、これはデバイス上ではfalseですが、iOSシミュレーターではtrueを返します。ドキュメンテーション:

arch(i386) ビルド構成は、コードが 32 ビット iOS シミュレータ用にコンパイルされると true を返します。

iOS以外のシミュレーター向けに開発している場合は、osパラメータを変更するだけで済みます。例:

watchOSシミュレーターを検出する

#if (arch(i386) || arch(x86_64)) && os(watchOS)
...
#endif

tvOSシミュレーターを検出する

#if (arch(i386) || arch(x86_64)) && os(tvOS)
...
#endif

あるいは、シミュレーターを検出する

#if (arch(i386) || arch(x86_64)) && (os(iOS) || os(watchOS) || os(tvOS))
...
#endif

代わりにランタイム チェックで問題がない場合は、シミュレータ上で true になるTARGET_OS_SIMULATOR変数 (またはTARGET_IPHONE_SIMULATORiOS 8 以前) を検査できます。

if/elseこれはプリプロセッサ フラグを使用する場合とは異なり、若干制限があることに注意してください。たとえば、構文的に無効な場所 (関数のスコープ外など)では使用できません。

たとえば、デバイスとシミュレーターで異なるインポートを実行したいとします。これは動的チェックでは不可能ですが、静的チェックでは簡単です。

#if (arch(i386) || arch(x86_64)) && os(iOS)
  import Foo
#else
  import Bar
#endif

また、フラグはSwift プリプロセッサによって0または に置き換えられるため、式で直接使用すると、コンパイラは到達不能なコードに関する警告を発します。1if/else

この警告を回避するには、他の回答のいずれかを参照してください。

おすすめ記事