如何以编程方式确定我的应用程序是否在 iPhone 模拟器中运行?
正如问题所述,我主要想知道我的代码是否在模拟器中运行,但也有兴趣了解正在运行或正在模拟的特定 iphone 版本。
编辑:我在问题名称中添加了“以编程方式”一词。 我的问题的重点是能够根据正在运行的版本/模拟器动态包含/排除代码,所以我真的在寻找类似预处理器指令之类的东西,可以为我提供此信息。
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.
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(21)
已经问过,但标题截然不同。
针对 iPhone 进行编译时 Xcode 设置的#defines
我将重复我的答案:
它位于 SDK 文档中的“有条件编译源代码”下。
相关定义是 TARGET_OS_SIMULATOR,它是在 iOS 框架内的 /usr/include/TargetConditionals.h 中定义的。 在工具链的早期版本中,您必须编写:
但在当前(Xcode 6/iOS8)工具链上不再需要这样做。
因此,例如,如果您想检查您是否正在设备上运行,您应该
根据适合您的用例进行操作。
Already asked, but with a very different title.
What #defines are set up by Xcode when compiling for iPhone
I'll repeat my answer from there:
It's in the SDK docs under "Compiling source code conditionally"
The relevant definition is TARGET_OS_SIMULATOR, which is defined in /usr/include/TargetConditionals.h within the iOS framework. On earlier versions of the toolchain, you had to write:
but this is no longer necessary on the current (Xcode 6/iOS8) toolchain.
So, for example, if you want to check that you are running on device, you should do
depending on which is appropriate for your use-case.
更新的代码:
据称这可以正式工作。
原始帖子(已弃用)
此代码将告诉您是否正在模拟器中运行。
Updated code:
This is purported to work officially.
Original post (since deprecated)
This code will tell you if you are running in a simulator.
不是预处理器指令,但这就是我在回答这个问题时所寻找的;
Not pre-processor directive, but this was what I was looking for when i came to this question;
Swift 现在有更好的方法。
自 Xcode 9.3及更新版本,可以使用
#if targetEnvironment(simulator)
来检查。There is a better way now in Swift.
As of Xcode 9.3 and newer, you can use
#if targetEnvironment(simulator)
to check.最好的方法是:
而不是
因为它总是定义为:0 或 1
The best way to do this is:
and not
since its always defined: 0 or 1
如果是 Swift,我们可以实现以下
我们可以创建结构,允许您创建结构化数据
然后如果我们想检测是否正在为 Swift 中的设备或模拟器构建应用程序。
In case of Swift we can implement following
We can create struct which allows you to create a structured data
Then If we wanted to Detect if app is being built for device or simulator in Swift then .
适用于 Swift 4.1 及更新版本和 Xcode 9.3 及更高版本
使用此代码:
Works for Swift 4.1 and newer and Xcode 9.3 and newer
Use this code:
所有这些答案都很好,但它在某种程度上让像我这样的新手感到困惑,因为它没有澄清编译检查和运行时检查。 预处理器在编译时之前,但我们应该让它更清楚
这篇博客文章显示如何检测iPhone模拟器?清楚
运行时
首先,我们简单讨论一下。 UIDevice 已经为您提供了有关设备的信息,
将根据应用程序的运行位置向您返回“iPhone Simulator”或“iPhone”。
编译时间
但是,您想要的是使用编译时间定义。 为什么? 因为您严格编译应用程序以在模拟器内部或设备上运行。 Apple 做了一个名为
TARGET_IPHONE_SIMULATOR
的定义。 那么让我们看一下代码: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? clearly
Runtime
First of all, let’s shortly discuss. UIDevice provides you already information about the device
will return you “iPhone Simulator” or “iPhone” according to where the app is running.
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
. So let’s look at the code :对于 Swift 4.2 / Xcode 10
我在 UIDevice 上创建了一个扩展,因此我可以轻松询问模拟器是否正在运行。
例如,在我的 AppDelegate 中,我使用此方法来决定是否需要注册远程通知,这对于模拟器来说是不可能的。
For Swift 4.2 / Xcode 10
I created an extension on UIDevice, so I can easily ask for if the simulator is running.
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.
以前的答案有点过时了。 我发现您需要做的就是查询
TARGET_IPHONE_SIMULATOR
宏(不需要包含任何其他头文件 [假设您正在为 iOS 编码])。我尝试了
TARGET_OS_IPHONE
,但在实际设备和模拟器上运行时它返回了相同的值 (1),这就是为什么我建议改用TARGET_IPHONE_SIMULATOR
。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]).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 usingTARGET_IPHONE_SIMULATOR
instead.快速:
从 检测应用程序是否正在为 Swift 中的设备或模拟器构建
In swift :
From Detect if app is being built for device or simulator in Swift
有没有人考虑过此处提供的答案?
我想 Objective-c 的等价物是
Has anyone considered the answer provided here?
I suppose the objective-c equivalent would be
我遇到了同样的问题,
TARGET_IPHONE_SIMULATOR
和TARGET_OS_IPHONE
始终被定义,并设置为 1。皮特的解决方案当然有效,但如果你碰巧在某些东西上构建除了英特尔(不太可能,但谁知道),只要 iphone 硬件不改变,这里有一些东西是安全的(所以你的代码将始终适用于当前的 iphone):将其放在方便的地方,然后假装
TARGET_*
常量定义正确。I had the same problem, both
TARGET_IPHONE_SIMULATOR
andTARGET_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):Put that somewhere convenient, and then pretend that the
TARGET_*
constants were defined correctly.包括所有类型的“模拟器”
To include all types of "simulators"
如果没有效果,试试这个
if nothing worked, try this
使用 Swift 4.2 (Xcode 10),我们可以做到这一点
With Swift 4.2 (Xcode 10), we can do this
我的回答基于@Daniel Magnusson 的回答以及@Nuthatch 和@n.Drake 的评论。 我编写它是为了为使用 iOS9 及更高版本的 swift 用户节省一些时间。
这对我有用:
My answer is based on @Daniel Magnusson answer and comments of @Nuthatch and @n.Drake. and I write it to save some time for swift users working on iOS9 and onwards.
This is what worked for me:
/// 如果是模拟器而不是设备则返回 true
/// Returns true if its simulator and not a device
Apple 添加了对检查应用程序是否针对模拟器的支持,具体如下:
Apple has added support for checking the app is targeted for the simulator with the following:
这对我最有效
This worked for me best
在我看来,答案(上面给出并在下面重复):
是最好的答案,因为它显然是在运行时执行的,而不是作为编译指令执行的。
In my opinion, the answer (presented above and repeated below):
is the best answer because it is obviously executed at RUNTIME versus being a COMPILE DIRECTIVE.