[解決済み】Swiftでアプリがデバイス用かシミュレータ用かを検出する方法
質問
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
の式で、コンパイラは到達不可能なコードに関する警告を出します。
この警告を回避するためには、他の回答を参照してください。
関連
-
[解決済み] Xcodeエラー "Could not find Developer Disk Image" が発生する。
-
[解決済み] 警告 xcode 6 で暗黙の変換により整数の精度が失われる
-
[解決済み] 制約条件の変更をアニメーションで表現するには?
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] Xcode 12、iOS Simulator用にビルドしても、iOS用にビルドされたオブジェクトファイルでは、アーキテクチャ「arm64」用にリンクされます。
-
[解決済み] フレームワークを使用したiOSアプリがデバイス上でクラッシュ、dyld: ライブラリがロードされない、Xcode 6 Beta
-
[解決済み] Swiftを使用してアプリのバージョンとビルド番号を取得するにはどうすればよいですか?
-
[解決済み] アプリのプレビュー用にiOSシミュレータのビデオをキャプチャー
-
[解決済み] Swiftでディレイを作成するには?
-
[解決済み】デバイスがiPhone Xであるかどうかを検出します。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】iOS用のプライベートメッセージUI(受信、送信、作成)フレームワークはありますか?
-
[解決済み] 'strcmp' はこのスコープで宣言されていません。
-
[解決済み】"宣言はファイルスコープでのみ有効 "について
-
[解決済み] リンカーコマンドが終了コード 1 で失敗した(起動を確認するには -v を使用)、Xcode 8、Swift 3
-
[解決済み] 新しい Swift クラスの void 関数で予期しない非 void の戻り値が発生する。
-
[解決済み] <UITabBarController: 0x197870> の外観遷移の開始/終了の呼び出しがアンバランスである。
-
[解決済み] 配列型 'int [16]' は代入不可能です。
-
[解決済み] Xcode 6: iOS 8.1 The Developer Disk Imageをマウントできませんでした。
-
[解決済み] UIViewAlertForUnsatisfiableConstraintsでトラップする方法は?
-
[解決済み】自分のアプリがiphoneシミュレーターで動作しているかどうかをプログラムで判断するには?