检测是否正在为Swift中的设备或模拟器构建应用程序 [英] Detect if app is being built for device or simulator in Swift

查看:103
本文介绍了检测是否正在为Swift中的设备或模拟器构建应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Objective-C中,我们可以知道是否正在使用宏为设备或模拟器构建应用程序:

In Objective-C we can know if an app is being built for device or simulator using macros:

#if TARGET_IPHONE_SIMULATOR
    // Simulator
#else
    // Device
#endif

这些是编译时宏,在运行时不可用。

These are compile time macros and not available at runtime.

如何在Swift中实现相同的功能?我搜索了堆栈溢出,看看文档,无法弄清楚。

How can I achieve the same in Swift? I searched stack overflow, had a look into the docs and cannot figure it out.

推荐答案

更新14/09/17



虽然这个答案可能有效,但建议的静态检查解决方案(由几位Apple工程师澄清)是定义一个针对iOS模拟器的自定义编译器标志。有关如何操作的详细说明,请参阅 @ mbelsky的答案

如果您需要进行静态检查(例如,如果不是运行时),则无法直接检测模拟器,但您可以检测iOS如下所示的桌面架构

If you need a static check (e.g. not a runtime if/else) you can't detect the simulator directly, but you can detect iOS on a desktop architecture like follows

#if (arch(i386) || arch(x86_64)) && os(iOS)
    ...
#endif

显然这是假的在设备上,但它在iOS模拟器中返回true,如文档

Clearly this is false on a device, but it returns true for the iOS Simulator, as specified in the documentation:


拱门(i386)构建配置在为32位iOS模拟器编译代码时返回true。

The arch(i386) build configuration returns true when code is compiled for the 32–bit iOS simulator.

如果您正在开发模拟器其他比iOS,你可以简单地改变 os 参数:例如

If you are developing for a simulator other than iOS, you can simply vary the os parameter: e.g.

检测 watchOS 模拟器

#if (arch(i386) || arch(x86_64)) && os(watchOS)
...
#endif

检测 tvOS 模拟器

#if (arch(i386) || arch(x86_64)) && os(tvOS)
...
#endif

或者,甚至,检测任何模拟器

Or, even, detect any simulator

#if (arch(i386) || arch(x86_64)) && (os(iOS) || os(watchOS) || os(tvOS))
...
#endif






如果你可以通过运行时检查,你可以检查 TARGET_OS_SIMULATOR 变量(或iOS 8及以下的 TARGET_IPHONE_SIMULATOR ),这在模拟器上是真实的。


If you instead are ok with a runtime check, you can inspect the TARGET_OS_SIMULATOR variable (or TARGET_IPHONE_SIMULATOR in iOS 8 and below), which is truthy on a simulator.

请注意,这是与使用预处理程序标志不同且稍微有限。例如,如果 if / else 在语法上无效(例如在函数范围之外),则无法使用它。

Please notice that this is different and slightly more limited than using a preprocessor flag. For instance you won't be able to use it in place where a if/else is syntactically invalid (e.g. outside of functions scopes).

例如,假设您希望在设备和模拟器上使用不同的导入。通过动态检查这是不可能的,而静态检查则是微不足道的。

Say, for example, that you want to have different imports on the device and on the simulator. This is impossible with a dynamic check, whereas it's trivial with a static check.

#if (arch(i386) || arch(x86_64)) && os(iOS)
  import Foo
#else
  import Bar
#endif

此外,由于swift预处理器将标志替换为 0 1 ,如果您直接在 if / else 表达式中使用它,编译器将发出有关无法访问代码的警告。

Also, since the flag is replaced with a 0 or a 1 by the swift preprocessor, if you directly use it in a if/else expression the compiler will raise a warning about unreachable code.

要解决此警告,请参阅其他答案之一。

In order to work around this warning, see one of the other answers.

这篇关于检测是否正在为Swift中的设备或模拟器构建应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆