Actualización 30/01/19
Si bien esta respuesta puede funcionar, la solución recomendada para una comprobación estática (como lo aclararon varios ingenieros de Apple) es definir un indicador de compilador personalizado dirigido a los simuladores de iOS. Para obtener instrucciones detalladas sobre cómo hacerlo, consulte la respuesta de @ mbelsky .
Respuesta original
Si necesita una comprobación estática (por ejemplo, no es un tiempo de ejecución si / no) no puede detectar el simulador directamente, pero puede detectar iOS en una arquitectura de escritorio de la siguiente manera
#if (arch(i386) || arch(x86_64)) && os(iOS)
...
#endif
Después de la versión Swift 4.1
El último uso, ahora directamente para todo en una condición para todos los tipos de simuladores necesita aplicar solo una condición:
#if targetEnvironment(simulator)
// your simulator code
#else
// your real device code
#endif
Para más aclaraciones, puede consultar la propuesta de Swift SE-0190
Para versión anterior -
Claramente, esto es falso en un dispositivo, pero devuelve verdadero para el Simulador de iOS, como se especifica en la documentación :
La configuración de compilación de arch (i386) vuelve verdadera cuando se compila el código para el simulador de iOS de 32 bits.
Si está desarrollando un simulador que no sea iOS, simplemente puede variar el os
parámetro: por ejemplo
Detecta el simulador de watchOS
#if (arch(i386) || arch(x86_64)) && os(watchOS)
...
#endif
Detecta el simulador de tvOS
#if (arch(i386) || arch(x86_64)) && os(tvOS)
...
#endif
O, incluso, detectar cualquier simulador
#if (arch(i386) || arch(x86_64)) && (os(iOS) || os(watchOS) || os(tvOS))
...
#endif
Si, en cambio, está de acuerdo con una verificación de tiempo de ejecución, puede inspeccionar la TARGET_OS_SIMULATOR
variable (o TARGET_IPHONE_SIMULATOR
en iOS 8 y versiones posteriores), lo cual es cierto en un simulador.
Tenga en cuenta que esto es diferente y un poco más limitado que usar un indicador de preprocesador. Por ejemplo, no podrá usarlo en el lugar donde a if/else
es sintácticamente inválido (por ejemplo, fuera de los ámbitos de funciones).
Digamos, por ejemplo, que desea tener diferentes importaciones en el dispositivo y en el simulador. Esto es imposible con una verificación dinámica, mientras que es trivial con una verificación estática.
#if (arch(i386) || arch(x86_64)) && os(iOS)
import Foo
#else
import Bar
#endif
Además, dado que el indicador es reemplazado por a 0
o a 1
por el preprocesador rápido, si lo usa directamente en una if/else
expresión, el compilador generará una advertencia sobre el código inalcanzable.
Para evitar esta advertencia, consulte una de las otras respuestas.