非常に古い歴史的な 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_SIMULATOR
iOS 8 以前) を検査できます。
if/else
これはプリプロセッサ フラグを使用する場合とは異なり、若干制限があることに注意してください。たとえば、構文的に無効な場所 (関数のスコープ外など)では使用できません。
たとえば、デバイスとシミュレーターで異なるインポートを実行したいとします。これは動的チェックでは不可能ですが、静的チェックでは簡単です。
#if (arch(i386) || arch(x86_64)) && os(iOS)
import Foo
#else
import Bar
#endif
また、フラグはSwift プリプロセッサによって0
または に置き換えられるため、式で直接使用すると、コンパイラは到達不能なコードに関する警告を発します。1
if/else
この警告を回避するには、他の回答のいずれかを参照してください。