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

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

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

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


当前回答

除了其他答案。

在Objective-c中,确保你包含了TargetConditionals。

# include < TargetConditionals.h >

在使用TARGET_OS_SIMULATOR之前。

其他回答

在Xcode 7.2(以及更早的版本,但我还没有测试过多少)中,你可以为“任何iOS模拟器”设置一个平台特定的构建标志“-D TARGET_IPHONE_SIMULATOR”。

查看“Swift Compiler - Customer Flags”下的项目构建设置,然后在“Other Swift Flags”中设置标志。当您将鼠标悬停在构建配置上时,可以通过单击“加号”图标来设置特定于平台的标志。

这样做有几个好处:1)你可以在Swift和Objective-C代码中使用相同的条件测试(“#if TARGET_IPHONE_SIMULATOR”)。2)你可以编译出只适用于每个版本的变量。

Xcode构建设置截图

从Swift 1.0开始,对我来说有用的是检查除了arm之外的架构:

#if arch(i386) || arch(x86_64)

     //simulator
#else 
     //device

#endif

swift 4.1已过时。请改用#if targetEnvironment(模拟器)。源

要检测Swift中的模拟器,您可以使用构建配置:

在Swift Compiler中定义此配置- d IOS_SIMULATOR - Custom Flags >其他Swift Flags 在下拉菜单中选择Any iOS Simulator SDK

现在你可以使用这个语句来检测模拟器:

#if IOS_SIMULATOR
    print("It's an iOS Simulator")
#else
    print("It's a device")
#endif

你也可以扩展UIDevice类:

extension UIDevice {
    var isSimulator: Bool {
        #if IOS_SIMULATOR
            return true
        #else
            return false
        #endif
    }
}
// Example of usage: UIDevice.current.isSimulator

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

我使用

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

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

除了其他答案。

在Objective-c中,确保你包含了TargetConditionals。

# include < TargetConditionals.h >

在使用TARGET_OS_SIMULATOR之前。