285

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

编辑:我在问题名称中添加了“以编程方式”这个词。我的问题的重点是能够根据正在运行的版本/模拟器动态包含/排除代码,所以我真的在寻找可以为我提供此信息的预处理器指令之类的东西。

4

21 回答 21

364

已经问过了,但标题完全不同。

为 iPhone 编译时 Xcode 设置了什么#defines

我将从那里重复我的答案:

它位于“有条件地编译源代码”下的 SDK 文档中

相关定义为TARGET_OS_SIMULATOR,定义在iOS框架内的/usr/include/TargetConditionals.h中。在工具链的早期版本中,您必须编写:

#include "TargetConditionals.h"

但这在当前(Xcode 6/iOS8)工具链上不再需要。

因此,例如,如果你想检查你是否在设备上运行,你应该这样做

#if TARGET_OS_SIMULATOR
    // Simulator-specific code
#else
    // Device-specific code
#endif

取决于哪个适合您的用例。

于 2009-01-19T17:17:02.990 回答
107

更新代码:

据称这是正式的工作。

#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
于 2009-01-19T17:10:38.010 回答
61

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

NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
    //device is simulator
}
于 2010-08-18T10:35:50.257 回答
55

最好的方法是:

#if TARGET_IPHONE_SIMULATOR

并不是

#ifdef TARGET_IPHONE_SIMULATOR

因为它总是定义:0或1

于 2011-03-07T07:05:41.863 回答
50

现在有更好的方法!

从 Xcode 9.3 beta 4 开始,您可以使用它#if targetEnvironment(simulator)来检查。

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

更新
Xcode 10 和 iOS 12 SDK 也支持这一点。

于 2018-03-12T13:50:51.950 回答
44

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

我们可以创建允许您创建结构化数据的结构

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
}
于 2016-02-25T04:48:57.257 回答
29

Swift 5和工作Xcode 12

使用此代码:

#if targetEnvironment(simulator)
   // Simulator
#else
   // Device
#endif
于 2018-07-18T19:06:11.443 回答
9

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

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

运行

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

[[UIDevice currentDevice] model]

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

编译时间

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

#if TARGET_IPHONE_SIMULATOR

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

#endif
于 2014-06-17T02:57:18.733 回答
6

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

我尝试TARGET_OS_IPHONE过,但在实际设备和模拟器上运行时它返回相同的值 (1),这就是我建议TARGET_IPHONE_SIMULATOR改用的原因。

于 2013-05-21T07:10:39.530 回答
6

迅速:

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

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

于 2016-06-16T14:10:55.910 回答
6

对于 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()
}
于 2018-11-25T13:29:03.363 回答
5

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

我想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);
    }
}
于 2017-07-26T13:59:51.397 回答
4

我有同样的问题,两者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_*常量定义正确。

于 2009-06-16T17:48:25.330 回答
1

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

NSString *model = [[UIDevice currentDevice] model];
if([model rangeOfString:@"Simulator" options:NSCaseInsensitiveSearch].location !=NSNotFound)
{
    // we are running in a simulator
}
于 2015-06-12T18:51:44.657 回答
1

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

#if targetEnvironment(simulator)
  //simulator code
#else 
  #warning("Not compiling for simulator")
#endif
于 2018-06-11T08:33:29.893 回答
0

我的回答基于@Daniel Magnusson 的回答和@Nuthatch 和@n.Drake 的评论。我写它是为了为在 iOS9 及更高版本上工作的 swift 用户节省一些时间。

这对我有用:

if UIDevice.currentDevice().name.hasSuffix("Simulator"){
    //Code executing on Simulator
} else{
    //Code executing on Device
}
于 2015-12-23T12:30:56.777 回答
0

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

public static var isSimulator: Bool {
    #if (arch(i386) || arch(x86_64)) && os(iOS)
        return true
    #else
        return false
    #endif
}
于 2018-02-28T13:39:48.843 回答
0

Apple 添加了对检查应用程序是否针对模拟器的支持,其中包括:

#if targetEnvironment(simulator)
let DEVICE_IS_SIMULATOR = true
#else
let DEVICE_IS_SIMULATOR = false
#endif
于 2018-07-11T22:43:52.933 回答
0

如果没有任何效果,试试这个

public struct Platform {

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

}
于 2018-09-17T13:33:26.323 回答
-4

这对我最有效

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


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

}
于 2016-05-11T06:40:11.530 回答
-5

在我看来,答案(上面提出并在下面重复):

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

是最好的答案,因为它显然是在运行时执行而不是作为编译指令。

于 2013-09-09T14:45:49.160 回答