在Objective-C中,我们可以使用宏知道应用程序是为设备还是模拟器构建的:

#if TARGET_IPHONE_SIMULATOR
    // Simulator
#else
    // Device
#endif

这些是编译时宏,在运行时不可用。

我如何在Swift中实现同样的目标?


当前回答

我不知道这是否对任何人有用,但至少M1 mac的当前版本似乎没有将SIMULATOR_MODEL_IDENTIFIER传递到NSProcessInfo

我使用

BOOL isMobile = [[NSProcessInfo processInfo].environment[@"USER"] isEqual:@"mobile"];

和迅捷的对等物。这可能很脆弱,但很有效。

其他回答

更新30/01/19

虽然这个答案可能有效,但静态检查的推荐解决方案(正如几个苹果工程师所澄清的那样)是定义一个针对iOS模拟器的自定义编译器标志。有关如何操作的详细说明,请参阅@mbelsky的回答。

原来的答案

如果你需要静态检查(例如,不是运行时If /else),你不能直接检测模拟器,但你可以在桌面架构上检测iOS,如下所示

#if (arch(i386) || arch(x86_64)) && os(iOS)
    ...
#endif

Swift 4.1版本之后

最新的使用,现在直接适用于所有在一个条件下所有类型的模拟器只需要适用一个条件-

#if targetEnvironment(simulator)
  // your simulator code
#else
  // your real device code
#endif

要了解更多信息,请查看Swift提案SE-0190


旧版本-

显然,这在设备上是false,但对于iOS模拟器,它返回true,如文档中所指定的:

当为32位iOS模拟器编译代码时,arch(i386)构建配置返回true。

如果你正在为iOS以外的模拟器开发,你可以简单地改变操作系统参数:

检测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

此外,由于该标志被swift预处理器替换为0或1,如果你直接在if/else表达式中使用它,编译器将发出关于不可访问代码的警告。

为了解决这个警告,请参阅其他答案之一。

我希望这个扩展可以派上用场。

extension UIDevice {
    static var isSimulator: Bool = {
        #if targetEnvironment(simulator)
        return true
        #else
        return false
        #endif
    }()
}

用法:

if UIDevice.isSimulator {
    print("running on simulator")
}

斯威夫特5.2.4 Xcode 11.7


 #if targetEnvironment(simulator)

 #endif

更新信息截至2018年2月20日

看起来@russbishop有一个权威的答案,使这个答案“不正确”-即使它似乎工作了很长一段时间。

检测应用程序是否正在构建的设备或模拟器在Swift

以前的回答

基于@WZW的回答和@Pang的评论,我创建了一个简单的实用结构。这个解决方案避免了@WZW的答案产生的警告。

import Foundation

struct Platform {

    static var isSimulator: Bool {
        return TARGET_OS_SIMULATOR != 0
    }

}

使用示例:

if Platform.isSimulator {
    print("Running on Simulator")
}

使用下面的代码:

#if targetEnvironment(simulator)
   // Simulator
#else
   // Device
#endif

适用于Swift 4和Xcode 9.4.1