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

时间:2009-01-19 16:55:33

标签: ios objective-c swift xcode ios-simulator

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

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

21 个答案:

答案 0 :(得分:349)

已经问过了,但标题却截然不同。

What #defines are set up by Xcode when compiling for iPhone

我会从那里重复我的回答:

它位于“有条件地编译源代码”

下的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

取决于哪种情况适合您的用例。

答案 1 :(得分:106)

更新了代码:

据称这是正式的。

#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

答案 2 :(得分:61)

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

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

答案 3 :(得分:54)

最好的方法是:

#if TARGET_IPHONE_SIMULATOR

而不是

#ifdef TARGET_IPHONE_SIMULATOR

因为它始终定义为:0或1

答案 4 :(得分:31)

如果是Swift,我们可以实施以下

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

struct Platform {
    static let isSimulator: Bool = {
        #if arch(i386) || arch(x86_64)
            return true
        #endif
        return false
    }()
}

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

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

答案 5 :(得分:29)

现在有一个更好的方式!

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

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

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

答案 6 :(得分:8)

所有这些答案都很好,但它有点像我一样混淆新手,因为它没有澄清编译检查和运行时检查。预处理器在编译之前,但我们应该更清楚

此博客文章明确显示How to detect the iPhone simulator?

<强>运行

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

[[UIDevice currentDevice] model]

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

编译时间

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

#if TARGET_IPHONE_SIMULATOR

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

#endif

答案 7 :(得分:6)

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

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

答案 8 :(得分:6)

在swift:

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

来自Detect if app is being built for device or simulator in Swift

答案 9 :(得分:6)

适用于Swift 4Xcode 9.4.1

使用此代码:

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

答案 10 :(得分:4)

我有同样的问题,TARGET_IPHONE_SIMULATORTARGET_OS_IPHONE总是被定义,并且设置为1.当然,Pete的解决方案是有效的,但是如果你碰巧建立在除了intel之外的东西上(不太可能,但谁知道),只要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_*常数被正确定义。

答案 11 :(得分:3)

对于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()
}

答案 12 :(得分:2)

是否有人考虑过here提供的答案?

我认为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);
    }
}

答案 13 :(得分:1)

包括所有类型的&#34;模拟器&#34;

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

答案 14 :(得分:1)

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

JAVA File

答案 15 :(得分:0)

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

这对我有用:

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

答案 16 :(得分:0)

///如果是模拟器而不是设备

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

答案 17 :(得分:0)

Apple通过以下方式增加了对检查应用程序是否针对模拟器的支持:

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

答案 18 :(得分:0)

如果没有任何效果,请尝试

public struct Platform {

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

}

答案 19 :(得分:-3)

这最适合我

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


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

}

答案 20 :(得分:-4)

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

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

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