在Objective-C中,我们可以知道是否正在使用宏为设备或模拟器构建应用程序:
#if TARGET_IPHONE_SIMULATOR // Simulator #else // Device #endif
这些是编译时宏,在运行时不可用。
如何在Swift中实现相同目标?
尽管此答案可能有效,但建议进行静态检查的解决方案(如几位Apple工程师所阐明的那样)是定义一个针对iOS模拟器的自定义编译器标志。
如果您需要静态检查(例如不需要运行时if/else),则无法直接检测到模拟器,但是可以在如下所示的桌面体系结构上检测iOS
#if (arch(i386) || arch(x86_64)) && os(iOS) ... #endif
之后 雨燕4.1 版本
最新用途,现在可以在一种情况下直接用于所有类型的模拟器,而只需要应用一种情况-
#if targetEnvironment(simulator) // your simulator code #else // your real device code #endif
有关更多说明,您可以查看 Swift 提案SE-0190
对于旧版本 -
显然,这在设备上为false,但对于iOS Simulator,返回的结果为true,如文档中所指定:
为32位iOS模拟器编译代码时,arch(i386)构建配置将返回true。
如果您是为iOS以外的模拟器开发的,则只需更改os参数即可:
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
相反,如果可以运行时检查,则可以检查TARGET_OS_SIMULATOR变量(或TARGET_IPHONE_SIMULATOR在iOS 8及更低版本中),这在模拟器上是正确的。
TARGET_OS_SIMULATOR
TARGET_IPHONE_SIMULATOR
请注意,这与使用预处理器标志不同,并且受到的限制更大。例如,您将无法在a if/else语法上无效的地方使用它(例如,在函数作用域之外)。
if/else
例如,假设您要在设备和模拟器上具有不同的导入。对于动态检查,这是不可能的,而对于静态检查,这是微不足道的。
#if (arch(i386) || arch(x86_64)) && os(iOS) import Foo #else import Bar #endif
另外,由于该标志被快速预处理器替换为a 0或a 1,因此,如果直接在if/else表达式中使用它,则编译器将发出有关代码无法到达的警告。
0
1
为了变通解决此警告,请参阅其他答案之一。