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

查看:28
本文介绍了如何检测是否正在为 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 中实现相同的目标?

推荐答案

更新 30/01/19

虽然此答案可能有效,但推荐的静态检查解决方案(如几位 Apple 工程师所澄清)是定义针对 iOS 模拟器的自定义编译器标志.有关如何处理的详细说明,请参阅 @mbelsky 的回答.

如果您需要静态检查(例如不是运行时 if/else),您无法直接检测模拟器,但您可以在桌面架构上检测 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

<小时>

Swift 4.1 版本之后

最新使用,现在直接用于多合一条件,所有类型模拟器只需要应用一个条件-

#if targetEnvironment(simulator)
  // your simulator code
#else
  // your real device code
#endif

有关更多说明,您可以查看 Swift 提案 SE-0190

对于旧版本 -

显然,这在设备上是错误的,但对于 iOS 模拟器,它返回 true,如 文档:

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

当为 32 位 iOS 模拟器编译代码时,arch(i386) 构建配置返回 true.

The arch(i386) build configuration returns true when the 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

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

#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 预处理器替换为 01,如果您直接在 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天全站免登陆