Aggiornamento 30/01/19
Sebbene questa risposta possa funzionare, la soluzione consigliata per un controllo statico (come chiarito da diversi ingegneri Apple) è quella di definire un flag di compilatore personalizzato destinato ai simulatori iOS. Per istruzioni dettagliate su come procedere, vedere la risposta di @ mbelsky .
Risposta originale
Se hai bisogno di un controllo statico (ad es. Non un runtime if / else) non puoi rilevare direttamente il simulatore, ma puoi rilevare iOS su un'architettura desktop come segue
#if (arch(i386) || arch(x86_64)) && os(iOS)
...
#endif
Dopo la versione Swift 4.1
Ultimo utilizzo, ora direttamente per tutti in una condizione per tutti i tipi di simulatori è necessario applicare una sola condizione:
#if targetEnvironment(simulator)
// your simulator code
#else
// your real device code
#endif
Per ulteriori chiarimenti, è possibile controllare la proposta Swift SE-0190
Per la versione precedente -
Chiaramente, questo è falso su un dispositivo, ma restituisce true per il simulatore iOS, come specificato nella documentazione :
La configurazione di build arch (i386) restituisce true quando il codice viene compilato per il simulatore iOS a 32 bit.
Se stai sviluppando un simulatore diverso da iOS, puoi semplicemente variare il os
parametro: ad es
Rileva il simulatore watchOS
#if (arch(i386) || arch(x86_64)) && os(watchOS)
...
#endif
Rileva il simulatore tvOS
#if (arch(i386) || arch(x86_64)) && os(tvOS)
...
#endif
O, persino, rilevare qualsiasi simulatore
#if (arch(i386) || arch(x86_64)) && (os(iOS) || os(watchOS) || os(tvOS))
...
#endif
Se invece stai bene con un controllo di runtime, puoi ispezionare la TARGET_OS_SIMULATOR
variabile (o TARGET_IPHONE_SIMULATOR
in iOS 8 e precedenti), che è davvero su un simulatore.
Si noti che questo è diverso e leggermente più limitato rispetto all'utilizzo di un flag di preprocessore. Ad esempio, non sarai in grado di usarlo nel posto in cui if/else
sintatticamente non è valido (ad esempio al di fuori degli ambiti delle funzioni).
Supponiamo, ad esempio, che desideri avere importazioni diverse sul dispositivo e sul simulatore. Questo è impossibile con un controllo dinamico, mentre è banale con un controllo statico.
#if (arch(i386) || arch(x86_64)) && os(iOS)
import Foo
#else
import Bar
#endif
Inoltre, poiché il flag viene sostituito con 0
ao 1
dal rapido preprocessore, se lo si utilizza direttamente in if/else
un'espressione, il compilatore genererà un avviso sul codice non raggiungibile.
Per aggirare questo avviso, vedere una delle altre risposte.