用于Apple Watch的预处理宏?

13

我正在查看苹果的Lister(适用于Apple Watch、iOS和OS X)示例。该示例对iOS和OS X执行测试:

#import <TargetConditionals.h>

#if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)

@import ListerKit;

#elif TARGET_OS_MAC

@import ListerKitOSX;

#endif

然而,没有针对或类似的测试。在中搜索没有结果:
$ 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条件是互斥的。 EMBEDDED / 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的嵌入式OS变体下运行     TARGET_OS_IPHONE      - 生成的代码将在TARGET_OS_MAC的iPhone OS变体下运行。 TARGET_IPHONE_SIMULATOR - 为在iPhone模拟器下运行生成代码 问题:Apple的手表有没有预处理器?


我正在使用标记,但我不确定这是否是正确的操作系统。

以下列表是从iPhone的TargetConditionals.h编译而来的。模拟器和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参数而不是第二个参数)。 - Top-Master
4个回答

26

你可以在TargetConditionals.h中找到各种目标条件(cmd + shift + o并输入TargetConditionals.h)。

在这个列表中,您可以找到像这样的列表以及许多其他有用的定义。 当前它包含TARGET_OS_WATCH自WatchOS 2以来。 对于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的"Build Configurations"一节下,您可以找到一个(希望)最新的包含所有当前可用值的列表。


1
这应该是被接受的答案。截至2019年,#if os(iOS) 仍然非常有效。当在iOS和watchOS上使用相同的类时,我需要这个来使 WCSessionDelegate 代码正常运行。 - John Robi

21

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

我正在使用watchOS 2的第一个早期测试版,所以可能会有变化,但是目前,在watchOS上将TARGET_OS_WATCH设置为1。

(还要小心:在watchOS上,TARGET_OS_IPHONE也设置为1,尽管TARGET_OS_IOS为0。)


8

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

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

使您的自定义标志成为独特的。苹果可能会在将来添加名为TARGET_WATCH_APP或其他名称的标志。在标志名称上使用前缀,使其特定于您。


1
在提问的时候,我应该接受这个答案。我不确定为什么没有接受。但是命运注定,苹果添加了TARGET_OS_WATCH。抱歉耽搁了。 - jww

2

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


你可以拥有一个共享的管理类,它调用 [UIApplication sharedApplication],虽然在手表上被禁止,但你知道它永远不会被调用,或者可能想要通过使用这个宏进行重写。 - donkey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接