【问题标题】:Preprocessor macro for Apple Watch?Apple Watch 的预处理器宏?
【发布时间】:2015-03-04 18:35:18
【问题描述】:

我正在查看 Apple 的 Lister (for Apple Watch, iOS, and OS X) 示例。该示例针对 iOS 和 OS X 执行测试:

#import <TargetConditionals.h>

#if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)

@import ListerKit;

#elif TARGET_OS_MAC

@import ListerKitOSX;

#endif

但是,没有针对 TARGET_OS_WATCH 或类似的测试。在TargetConditionals.h 中搜索watch 不会产生任何命中:

$ cat /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer
  /SDKs/iPhoneOS7.1.sdk/usr/include/TargetConditionals.h | grep -i watch
$

来自TargetConditionals.h,我知道有:

 这些条件指定生成的代码将在哪个操作系统中
    跑步。 MAC/WIN32/UNIX 条件是互斥的。嵌入式/iPhone
    条件是 TARGET_OS_MAC 的变体。

        TARGET_OS_MAC - 生成代码将在 Mac OS 下运行
        TARGET_OS_WIN32 - 生成代码将在 32 位 Windows 下运行
        TARGET_OS_UNIX - 生成代码将在某些非 Mac OS X unix 下运行
        TARGET_OS_EMBEDDED - 生成代码将在嵌入式操作系统变体下运行
                                  TARGET_OS_MAC
        TARGET_OS_IPHONE - 生成代码将在 iPhone OS 下运行
                                  是 TARGET_OS_MAC 的变体。
    TARGET_IPHONE_SIMULATOR - 生成在 iPhone 模拟器下运行的代码

问题:苹果手表有预处理器吗?


我使用 进行标记,但我不确定这是否是此问题的正确操作系统。

以下列表来自 iPhone 的TargetConditionals.h。 Simulator 和 OS X 类似(它们只是将不同的位设置为 1):

#define TARGET_OS_MAC               1
#define TARGET_OS_WIN32             0
#define TARGET_OS_UNIX              0
#define TARGET_OS_EMBEDDED          1 
#define TARGET_OS_IPHONE            1 
#define TARGET_IPHONE_SIMULATOR     0 

问题:手表使用TARGET_OS_EMBEDDED吗?手表省略TARGET_OS_IPHONE吗?

【问题讨论】:

  • clang 正在编译时,-target ${ARCH}-apple-watchos6.2 命令行参数和-mwatchos-version-min=6.2 参数会导致定义正确的宏(并且模拟器构建传递-mwatchsimulator-version-min=6.2 arg 而不是第二个)

标签: ios ios preprocessor watchkit c-preprocessor watchos-2


【解决方案1】:

您可以在 TargetConditionals.h 中找到所有类型的目标条件(cmd + shift + o 并键入 TargetConditionals.h)。

在此列表中,您可以找到这样的列表以及更多有用的定义。 目前它确实包含自 WatchOS 2 以来的 TARGET_OS_WATCH。对于 WatchOS 1,无法在手表上运行自定义代码,因此当时不需要它,因为一切都在手机本身上运行。

#define TARGET_OS_MAC               1
#define TARGET_OS_WIN32             0
#define TARGET_OS_UNIX              0
#define TARGET_OS_IPHONE            1 
#define TARGET_OS_IOS               0
#define TARGET_OS_WATCH             1
#define TARGET_OS_TV                0
#define TARGET_OS_SIMULATOR         0
#define TARGET_OS_EMBEDDED          1 

快速加法

#if os(watchOS)
    [Watch code]
#else
    [Code for iOS, appleTV, or any else clause]
#endif

其他一些有效值:iOS、OSX、tvOS

关于这个和更多的小解释http://nshipster.com/swift-system-version-checking/

在本文档的底部 https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html#//apple_ref/doc/uid/TP40014216-CH8-XID_15#Build 配置 在“构建配置”部分下,您可以找到一个(希望)最新列表,其中包含当前可用的所有这些值

【讨论】:

  • 这应该是公认的答案。截至 2019 年,#if os(iOS) 仍然很好用。在 iOS 和 watchOS 中使用同一个类时,我需要这样做才能使 WCSessionDelegate 代码正常运行。
【解决方案2】:

从 watchOS 2.0 开始,您可以在手表上运行本机代码,因此这是一个更相关的问题。

我正在使用 watchOS 2 的第一个早期测试版,所以这可能会改变,但现在,TARGET_OS_WATCH 在 watchOS 上设置为 1。

(另外,请注意:TARGET_OS_IPHONE 在 watchOS 上也设置为 1,尽管 TARGET_OS_IOS 为 0。)

【讨论】:

    【解决方案3】:

    没有 WatchKit 或应用扩展目标条件。但是您可以创建自己的每个目标条件,并以相同的方式使用。

    如果您查看任何目标的“构建设置”部分,都会有一个名为“其他 C 标志”的部分。为 WatchKit 目标添加一个条目。如果添加-DMY_WATCHKIT_FLAG=1 之类的内容,则可以在代码中执行#if MY_WATCHKIT_FLAG

    制作您的自定义标志,好吧,自定义。 Apple 将来可能会添加一个名为 TARGET_WATCH_APP 之类的标志,这并非不可能。在标志名称上使用前缀使其特定于您。

    【讨论】:

    • 在提出问题的时候,我应该已经接受了这个答案。我不知道为什么我没有。但正如命运所愿,苹果添加了TARGET_OS_WATCH。抱歉耽搁了。
    【解决方案4】:

    使用当前的 WatchKit SDK,Watch 应用程序中的所有代码都在与之配对的手机上运行,​​因此您的预处理器不会遇到将在 Watch 上运行的代码,因此对于宏告诉它什么时候做。您链接到的示例的 ListerWatch 目标中的代码将作为扩展程序在 iPhone 上运行,并通过 WatchKit 与其手表 UI 对话。

    【讨论】:

    • 您可以拥有一个共享管理器类,该类调用 [UIApplication sharedApplication] 禁止在手表上使用,但您知道永远不会被调用或可能希望使用此宏覆盖。
    猜你喜欢
    • 1970-01-01
    • 2015-04-15
    • 2015-07-31
    • 2010-09-19
    • 2020-02-09
    • 1970-01-01
    • 2011-01-26
    • 1970-01-01
    相关资源
    最近更新 更多