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

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

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

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


当前回答

斯威夫特5.2.4 Xcode 11.7


 #if targetEnvironment(simulator)

 #endif

其他回答

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

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

用法:

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

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

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

     //simulator
#else 
     //device

#endif

TARGET_IPHONE_SIMULATOR在iOS 9中已弃用。TARGET_OS_SIMULATOR是替换。TARGET_OS_EMBEDDED也是可用的。

从targetconditions .h:

#如果定义(__GNUC__) & &(定义(__APPLE_CPP__) | |定义(__APPLE_CC__) | | (__MACOS_CLASSIC__)定义) …… #定义TARGET_OS_SIMULATOR 0 #定义TARGET_OS_EMBEDDED #定义TARGET_IPHONE_SIMULATOR TARGET_OS_SIMULATOR /* deprecated */ #定义TARGET_OS_NANO TARGET_OS_WATCH

让我在这里澄清一些事情:

TARGET_OS_SIMULATOR在很多情况下在Swift代码中没有设置;由于桥接头,您可能会意外地导入它,但这是脆弱的,不受支持。这在框架中甚至是不可能的。这就是为什么有些人对这在Swift中是否有效感到困惑。 我强烈建议不要使用架构来代替模拟器。

执行动态检查:

检查ProcessInfo.processInfo。environment["SIMULATOR_DEVICE_NAME"] != nil完全没问题。

您还可以通过检查SIMULATOR_MODEL_IDENTIFIER来获得正在模拟的底层模型,它将返回像iPhone10,3这样的字符串。

执行静态检查:

Xcode 9.2及更早版本:定义你自己的Swift编译标志(如其他答案所示)。

Xcode 9.3+使用新的targetenvirenvironment条件:

#if targetEnvironment(simulator)
    // for sim only
#else
    // for device
#endif

来自Xcode 9.3

#if targetEnvironment(simulator)

Swift supports a new platform condition targetEnvironment with a single valid argument simulator. Conditional compilation of the form '#if targetEnvironment(simulator)' can now be used to detect when the build target is a simulator. The Swift compiler will attempt to detect, warn, and suggest the use of targetEnvironment(simulator) when evaluating platform conditions that appear to be testing for simulator environments indirectly, via the existing os() and arch() platform conditions. (SE-0190)

iOS 9+:

extension UIDevice {
    static var isSimulator: Bool {
        return NSProcessInfo.processInfo().environment["SIMULATOR_DEVICE_NAME"] != nil
    }
}

斯威夫特3:

extension UIDevice {
    static var isSimulator: Bool {
        return ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil
    }
}

iOS 9之前:

extension UIDevice {
    static var isSimulator: Bool {
        return UIDevice.currentDevice().model == "iPhone Simulator"
    }
}

objective - c:

@interface UIDevice (Additions)
- (BOOL)isSimulator;
@end

@implementation UIDevice (Additions)

- (BOOL)isSimulator {
    if([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){9, 0, 0}]) {
        return [NSProcessInfo processInfo].environment[@"SIMULATOR_DEVICE_NAME"] != nil;
    } else {
        return [[self model] isEqualToString:@"iPhone Simulator"];
    }
}

@end