在 Objective-C 中,我们可以使用宏知道应用程序是为设备还是模拟器构建的:
#if TARGET_IPHONE_SIMULATOR
// Simulator
#else
// Device
#endif
这些是编译时宏,在运行时不可用。
我如何在 Swift 中实现相同的目标?
最佳答案
2019 年 1 月 30 日更新
虽然这个答案可能有效,但推荐的静态检查解决方案(正如几位 Apple 工程师所阐明的那样)是定义一个针对 iOS 模拟器的自定义编译器标志。有关如何操作的详细说明,请参阅 @mbelsky's answer .
原始答案
如果您需要静态检查(例如,不是运行时 if/else),您无法直接检测模拟器,但您可以在桌面架构上检测 iOS,如下所示
#if (arch(i386) || arch(x86_64)) && os(iOS)
...
#endif
Swift 4.1 版本之后
Latest use, now directly for all in one condition for all types of simulators need to apply only one condition -
#if targetEnvironment(simulator)
// your simulator code
#else
// your real device code
#endif
如需更多说明,您可以查看 Swift 提案 SE-0190
For older version -
很明显,这在设备上是错误的,但它对 iOS 模拟器返回真,如 documentation 中指定的那样:
The arch(i386) build configuration returns true when the code is compiled for the 32–bit iOS simulator.
如果您正在为 iOS 以外的模拟器开发,您可以简单地改变 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
变量(在 iOS 8 及以下版本中为 TARGET_IPHONE_SIMULATOR
),这在模拟器上是真实的。
请注意,这与使用预处理器标志不同,并且略有限制。例如,您将无法在 if/else
的地方使用它。在语法上是无效的(例如,在函数范围之外)。
例如,您希望在设备和模拟器上进行不同的导入。这对于动态检查是不可能的,而对于静态检查则微不足道。
#if (arch(i386) || arch(x86_64)) && os(iOS)
import Foo
#else
import Bar
#endif
此外,由于标志被替换为 0
或 1
通过 swift 预处理器,如果你直接在 if/else
中使用它编译器将发出有关无法访问代码的警告。
要解决此警告,请参阅其他答案之一。
关于ios - 如何检测是否正在为 Swift 中的设备或模拟器构建应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27281931/