我如何以编程方式确定我的应用程序是否在iphone模拟器中运行?

正如问题所述,我主要想知道我的代码是否在模拟器中运行,但也有兴趣知道正在运行或正在模拟的特定iphone版本。

编辑:我在问题名称中添加了“以编程方式”这个词。我的问题的要点是能够动态包括/排除代码取决于哪个版本/模拟器正在运行,所以我真的在寻找像一个预处理程序指令,可以为我提供这个信息。

127683 次浏览

更新后的代码:

官方声称这是有效的。

#if TARGET_IPHONE_SIMULATOR
NSString *hello = @"Hello, iPhone simulator!";
#elif TARGET_OS_IPHONE
NSString *hello = @"Hello, device!";
#else
NSString *hello = @"Hello, unknown target!";
#endif

原帖子(弃用)

这段代码将告诉您是否在模拟器中运行。

#ifdef __i386__
NSLog(@"Running in the simulator");
#else
NSLog(@"Running on a device");
#endif

我遇到了同样的问题,TARGET_IPHONE_SIMULATORTARGET_OS_IPHONE总是被定义,并被设置为1。Pete的解决方案当然有效,但如果你碰巧构建在英特尔以外的东西上(不太可能,但谁知道呢),这里有一些东西是安全的,只要iphone硬件不改变(所以你的代码将永远适用于当前的iphone):

#if defined __arm__ || defined __thumb__
#undef TARGET_IPHONE_SIMULATOR
#define TARGET_OS_IPHONE
#else
#define TARGET_IPHONE_SIMULATOR 1
#undef TARGET_OS_IPHONE
#endif

把它放在方便的地方,然后假装TARGET_*常量被正确定义。

不是预处理器指令,但这是我在研究这个问题时所寻找的;

NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
//device is simulator
}

最好的方法是:

#if TARGET_IPHONE_SIMULATOR

而不是

#ifdef TARGET_IPHONE_SIMULATOR

因为它总是定义为0或1

之前的答案有点过时了。我发现你所需要做的就是查询TARGET_IPHONE_SIMULATOR宏(不需要包含任何其他头文件[假设你是为iOS编码])。

我尝试了TARGET_OS_IPHONE,但它在实际设备和模拟器上运行时返回相同的值(1),这就是为什么我建议使用TARGET_IPHONE_SIMULATOR代替。

在我看来,答案(如上所述,下文重复):

NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
//device is simulator
}

是最好的答案,因为它显然是在RUNTIME执行,而不是作为一个COMPILE指令。

所有这些答案都很好,但它在某种程度上让像我这样的新手感到困惑,因为它没有阐明编译检查和运行时检查。预处理器在编译之前,但我们应该更清楚

这篇博客文章清楚地展示了如何检测iPhone模拟器?

运行时

首先,让我们简单讨论一下。UIDevice已经为您提供了有关设备的信息

[[UIDevice currentDevice] model]

将根据应用程序运行的位置返回“iPhone模拟器”或“iPhone”。

编译时

但是,您需要的是使用编译时定义。为什么?因为你严格编译你的应用程序,要么在模拟器中运行,要么在设备上运行。Apple做了一个名为TARGET_IPHONE_SIMULATOR的定义。让我们看一下代码:

#if TARGET_IPHONE_SIMULATOR


NSLog(@"Running in Simulator - no app store or giro");


#endif

包括所有类型的“模拟器”

NSString *model = [[UIDevice currentDevice] model];
if([model rangeOfString:@"Simulator" options:NSCaseInsensitiveSearch].location !=NSNotFound)
{
// we are running in a simulator
}

我的回答是基于@Daniel Magnusson的回答和@Nuthatch和@n.Drake的评论。我写它是为了为在iOS9及以后的系统上快速工作的用户节省一些时间。

这对我来说很管用:

if UIDevice.currentDevice().name.hasSuffix("Simulator"){
//Code executing on Simulator
} else{
//Code executing on Device
}

在Swift的情况下,我们可以实现以下

我们可以创建struct,它允许你创建结构化数据

struct Platform {
static var isSimulator: Bool {
#if targetEnvironment(simulator)
// We're on the simulator
return true
#else
// We're on a device
return false
#endif
}
}

然后,如果我们想检测应用程序是否正在构建的设备或模拟器在Swift然后。

if Platform.isSimulator {
// Do one thing
} else {
// Do the other
}

这对我来说是最有效的

NSString *name = [[UIDevice currentDevice] name];




if ([name isEqualToString:@"iPhone Simulator"]) {


}

用swift:

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

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

有没有人考虑过在这里提供的答案?

我想objective-c的等价物是

+ (BOOL)isSimulator {
NSOperatingSystemVersion ios9 = {9, 0, 0};
NSProcessInfo *processInfo = [NSProcessInfo processInfo];
if ([processInfo isOperatingSystemAtLeastVersion:ios9]) {
NSDictionary<NSString *, NSString *> *environment = [processInfo environment];
NSString *simulator = [environment objectForKey:@"SIMULATOR_DEVICE_NAME"];
return simulator != nil;
} else {
UIDevice *currentDevice = [UIDevice currentDevice];
return ([currentDevice.model rangeOfString:@"Simulator"].location != NSNotFound);
}
}

///如果它的模拟器不是设备,则返回true

public static var isSimulator: Bool {
#if (arch(i386) || arch(x86_64)) && os(iOS)
return true
#else
return false
#endif
}

Swift现在有了更好的方式。

对于Xcode 9.3和更新的版本,可以使用#if targetEnvironment(simulator)进行检查。

#if targetEnvironment(simulator)
//Your simulator code
#endif

在Swift 4.2 (Xcode 10)中,我们可以做到这一点

#if targetEnvironment(simulator)
//simulator code
#else
#warning("Not compiling for simulator")
#endif

苹果增加了对检查应用程序是针对模拟器的支持,如下:

#if targetEnvironment(simulator)
let DEVICE_IS_SIMULATOR = true
#else
let DEVICE_IS_SIMULATOR = false
#endif

适用于< >强劲迅速4.1 < / >强和更新版本以及< >强Xcode 9.3 < / >强和更新版本

使用以下代码:

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

如果没有效果,试试这个

public struct Platform {


public static var isSimulator: Bool {
return TARGET_OS_SIMULATOR != 0 // Use this line in Xcode 7 or newer
}


}

Swift 4.2 / Xcode 10

我在UIDevice上创建了一个扩展,所以我可以很容易地询问模拟器是否正在运行。

// UIDevice+CheckSimulator.swift


import UIKit


extension UIDevice {
    

/// Checks if the current device that runs the app is xCode's simulator
static func isSimulator() -> Bool {
#if targetEnvironment(simulator)
return true
#else
return false
#endif
}
}

以我的AppDelegate为例,我使用这个方法来决定是否需要为远程通知注册,这对于模拟器来说是不可能的。

// CHECK FOR REAL DEVICE / OR SIMULATOR
if UIDevice.isSimulator() == false {
        

// REGISTER FOR SILENT REMOTE NOTIFICATION
application.registerForRemoteNotifications()
}