1. ホーム
  2. アイオス

[解決済み】Swiftでアプリがデバイス用かシミュレータ用かを検出する方法

2022-03-29 17:26:51

質問

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

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

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

Swiftで同じことを実現するにはどうしたらいいですか?

どのように解決するのですか?

30/01/19更新

この回答は有効かもしれませんが、静的チェックの推奨されるソリューションは(複数のAppleエンジニアによって明らかにされたように)、iOS Simulatorsを対象とするカスタムコンパイラフラグを定義することです。その方法の詳細については、以下を参照してください。 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

より明確な説明のために スウィフト 提案 SE-0190


旧バージョンの場合 -

明らかにデバイス上では false ですが、iOS Simulator では true を返し、指定された ドキュメント :

arch(i386) ビルド構成は、コードが 32-bit iOS シミュレータ用にコンパイルされた場合、true を返します。

iOS 以外のシミュレータ向けに開発する場合は、単純に os パラメータを使用します。

を検出します。 ウォッチオーエス シミュレーター

#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


その代わり、実行時のチェックがOKなら TARGET_OS_SIMULATOR 変数(または TARGET_IPHONE_SIMULATOR iOS 8以下では、シミュレータ上で真実になります。

これは、プリプロセッサ・フラグを使用するのとは異なり、若干の制限があることにご留意ください。例えば、このフラグは if/else は構文的に無効です(例:関数のスコープ外)。

例えば、デバイスとシミュレータで異なるインポートをしたい場合を考えてみましょう。動的なチェックでは不可能ですが、静的なチェックでは簡単です。

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

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

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