简体   繁体   English

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

[英]How can I programmatically determine if my app is running in the iphone simulator?

As the question states, I would mainly like to know whether or not my code is running in the simulator, but would also be interested in knowing the specific iphone version that is running or being simulated.正如问题所述,我主要想知道我的代码是否在模拟器中运行,但也有兴趣了解正在运行或正在模拟的特定 iphone 版本。

EDIT: I added the word 'programmatically' to the question name.编辑:我在问题名称中添加了“以编程方式”这个词。 The point of my question is to be able to dynamically include / exclude code depending on which version / simulator is running, so I'd really be looking for something like a pre-processor directive that can provide me this info.我的问题的重点是能够根据正在运行的版本/模拟器动态包含/排除代码,所以我真的会寻找像预处理器指令这样的东西可以为我提供这些信息。

Already asked, but with a very different title.已经问过了,但标题非常不同。

What #defines are set up by Xcode when compiling for iPhone Xcode 在为 iPhone 编译时设置了什么 #defines

I'll repeat my answer from there:我将从那里重复我的回答:

It's in the SDK docs under "Compiling source code conditionally"它位于“有条件地编译源代码”下的 SDK 文档中

The relevant definition is TARGET_OS_SIMULATOR, which is defined in /usr/include/TargetConditionals.h within the iOS framework.相关的定义是TARGET_OS_SIMULATOR,它在iOS框架内的/usr/include/TargetConditionals.h中定义。 On earlier versions of the toolchain, you had to write:在早期版本的工具链上,您必须编写:

#include "TargetConditionals.h"

but this is no longer necessary on the current (Xcode 6/iOS8) toolchain.但这在当前(Xcode 6/iOS8)工具链上不再需要。

So, for example, if you want to check that you are running on device, you should do因此,例如,如果您想检查您是否在设备上运行,您应该这样做

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

depending on which is appropriate for your use-case.取决于哪个适合您的用例。

Updated code:更新代码:

This is purported to work officially.据说这是正式工作。

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

Original post (since deprecated)原始帖子(已弃用)

This code will tell you if you are running in a simulator.此代码将告诉您是否在模拟器中运行。

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

Not pre-processor directive, but this was what I was looking for when i came to this question;不是预处理器指令,但这正是我遇到这个问题时所寻找的;

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

The best way to do this is:最好的方法是:

#if TARGET_IPHONE_SIMULATOR

and not而不是

#ifdef TARGET_IPHONE_SIMULATOR

since its always defined: 0 or 1因为它总是定义:0 或 1

THERE IS A BETTER WAY NOW!现在有更好的方法!

As of Xcode 9.3 beta 4 you can use #if targetEnvironment(simulator) to check.从 Xcode 9.3 beta 4 开始,您可以使用#if targetEnvironment(simulator)进行检查。

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

UPDATE更新
Xcode 10 and iOS 12 SDK supports this too. Xcode 10 和 iOS 12 SDK 也支持这一点。

In case of Swift we can implement following在 Swift 的情况下,我们可以实现以下

We can create struct which allows you to create a structured data我们可以创建允许您创建结构化数据的结构

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
    }
}

Then If we wanted to Detect if app is being built for device or simulator in Swift then .然后,如果我们想检测应用程序是在 Swift 中为设备还是模拟器构建的,那么 .

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

Works for Swift 5 and Xcode 12适用于Swift 5Xcode 12

Use this code:使用此代码:

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

All those answer are good, but it somehow confuses newbie like me as it does not clarify compile check and runtime check.所有这些答案都很好,但它以某种方式让像我这样的新手感到困惑,因为它没有澄清编译检查和运行时检查。 Preprocessor are before compile time, but we should make it clearer预处理器在编译时间之前,但我们应该说得更清楚

This blog article shows How to detect the iPhone simulator?这篇博客文章展示了如何检测 iPhone 模拟器? clearly清楚地

Runtime运行时

First of all, let's shortly discuss.首先,让我们简短地讨论一下。 UIDevice provides you already information about the device UIDevice 已为您提供有关设备的信息

[[UIDevice currentDevice] model]

will return you “iPhone Simulator” or “iPhone” according to where the app is running.将根据应用程序运行的位置返回“iPhone Simulator”或“iPhone”。

Compile time编译时间

However what you want is to use compile time defines.但是,您想要的是使用编译时定义。 Why?为什么? Because you compile your app strictly to be run either inside the Simulator or on the device.因为您严格编译应用程序以在模拟器内或设备上运行。 Apple makes a define called TARGET_IPHONE_SIMULATOR . Apple 做了一个名为TARGET_IPHONE_SIMULATOR的定义。 So let's look at the code :那么让我们看一下代码:

#if TARGET_IPHONE_SIMULATOR

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

#endif

The previous answers are a little dated.以前的答案有点过时了。 I found that all you need to do is query the TARGET_IPHONE_SIMULATOR macro ( no need to include any other header files [assuming you are coding for iOS]).我发现您需要做的就是查询TARGET_IPHONE_SIMULATOR宏(无需包含任何其他头文件[假设您正在为 iOS 编码])。

I attempted TARGET_OS_IPHONE but it returned the same value (1) when running on an actual device and simulator, that's why I recommend using TARGET_IPHONE_SIMULATOR instead.我尝试了TARGET_OS_IPHONE但它在实际设备和模拟器上运行时返回相同的值 (1),这就是我建议使用TARGET_IPHONE_SIMULATOR的原因。

For Swift 4.2 / xCode 10对于 Swift 4.2 / xCode 10

I created an extension on UIDevice, so I can easily ask for if the simulator is running.我在 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
    }
}

In my AppDelegate for example I use this method to decide wether registering for remote notification is necessary, which is not possible for the simulator.例如,在我的AppDelegate 中,我使用此方法来决定是否需要注册远程通知,这对于模拟器来说是不可能的。

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

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

I had the same problem, both TARGET_IPHONE_SIMULATOR and TARGET_OS_IPHONE are always defined, and are set to 1. Pete's solution works, of course, but if you ever happen to build on something other than intel (unlikely, but who knows), here's something that's safe as long as the iphone hardware doesn't change (so your code will always work for the iphones currently out there):我遇到了同样的问题, 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

Put that somewhere convenient, and then pretend that the TARGET_* constants were defined correctly.把它放在方便的地方,然后假装TARGET_*常量定义正确。

Has anyone considered the answer provided here ?有没有人考虑过这里提供的答案?

I suppose the objective-c equivalent would be我想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);
    }
}

To include all types of "simulators"包括所有类型的“模拟器”

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

With Swift 4.2 (Xcode 10), we can do this使用 Swift 4.2 (Xcode 10),我们可以做到这一点

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

My answer is based on @Daniel Magnusson answer and comments of @Nuthatch and @n.Drake.我的回答基于@Daniel Magnusson 的回答以及@Nuthatch 和@n.Drake 的评论。 and I write it to save some time for swift users working on iOS9 and onwards.我写它是为了为在 iOS9 及更高版本上工作的快速用户节省一些时间。

This is what worked for me:这对我有用:

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

/// Returns true if its simulator and not a device /// 如果是模拟器而不是设备则返回真

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

Apple has added support for checking the app is targeted for the simulator with the following: Apple 添加了对检查应用程序是否针对模拟器的支持,如下所示:

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

if nothing worked, try this如果没有任何效果,试试这个

public struct Platform {

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

}

This worked for me best这对我最有效

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


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

}

In my opinion, the answer (presented above and repeated below):在我看来,答案(在上面提出并在下面重复):

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

is the best answer because it is obviously executed at RUNTIME versus being a COMPILE DIRECTIVE.是最好的答案,因为它显然是在运行时执行的,而不是编译指令。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 您如何以编程方式确定iPhone X Simulator? - How can you determine iPhone X Simulator programmatically? 如何获得以编程方式在模拟器上运行的应用的SDK版本? - how do I get the SDK version for an app running on the simulator programmatically? 我的应用程序在我的iPhone上运行时崩溃,但不在模拟器中崩溃。 我可以使用哪些调试技术来解决问题? - My app crashes when running on my iPhone, but not in the simulator. What are some debugging techniques I can use to reso the issue? 如何以编程方式确定iPhone上的默认铃声? - How can I programmatically determine the default ringtone on an iPhone? 如何在iPhone模拟器文件夹下找到我的应用程序文件? - How can I find my app files under iPhone Simulator folder? 如何从模拟器录制iPhone应用程序的视频? - How do I record a video of my iPhone app from the simulator? 应用程序[iphone]是否可以通过程序确定是否正在运行其他特定应用程序? - Is there a way for an app[iphone] to determine programmatically if another specific app is running? iPhone模拟器 - 如何检测应用程序何时在模拟器上运行(这样可以设置测试数据)? - iPhone simulator - how to detect when app is running on simulator (so can setup test data)? 如何确定Springs and Struts应用程序是否正在iPhone 6模拟器中扩展? - How can I tell if a Springs and Struts app is scaling in the iPhone 6 simulator? 为什么应用程序在iPhone模拟器中崩溃? 我怎样才能解决这个问题? - Why is app crashing in iPhone simulator; how can I fix this?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM