检测运行目标是应用扩展还是iOS应用

19

我有一个简单的应用程序,还有一个 iOS 8 的“今天”扩展(或小部件)。我正在做的其中一件事是在我的应用程序和小部件之间共享代码类,因为这显然可以避免我拥有同样代码的多个副本。除了一个问题,它工作得很好,但我遇到了一个问题,因为不能在 iOS 8 小部件上使用 UIApplication sharedApplication API,所以会出现错误。

所以我想,可以编写一个简单的if语句,检查最终目标是本机应用程序还是 iOS 8 小部件,然后根据需要添加相应的代码。这样行得通吗?

这是我的代码:

if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]))
    {
        CGSize ssz = sz;
        sz = CGSizeMake(ssz.height, ssz.width);
    }

我该如何修改这段代码以实现以下操作之一:

  1. 仅当最终目标是本机iOS应用而不是小部件时才运行/编译IF
  2. 或者检查目标平台上是否可用该API,如果可用,则使用该API?

希望我的问题表述清晰,感谢您的时间,丹。


@supertecnoboff 仅出于兴趣,你认为呢? - user4657588
3个回答

35

运行时检查不可用,因为Xcode不允许编译使用sharedApplication的扩展代码。它必须是编译时检查。

不幸的是,这个检查没有内置到程序中,您需要添加它。您需要执行以下操作:

  1. 在今天的扩展项目设置中,在“其他C标志”下,添加自己的自定义编译器宏。对于名为TODAY_EXTENSION的宏,添加-DTODAY_EXTENSION:

enter image description here

  1. In your code, check this macro using something like

    #ifndef TODAY_EXTENSION
    ... app-only code here ...
    #endif
    

    Conversely, code that should only exist in the extension would look like

    #ifdef TODAY_EXTENSION
    ... extension-only code here ...
    #endif
    

1
那么你可以在那些#ifndef语句中添加else语句吗? - user4657588
你知道为什么苹果在iOS 8扩展中禁止了sharedApplication吗? - user4657588
如果需要,您可以使用#else。您可以使用整个C预处理器,它可以做很多事情。至于sharedApplication,这是因为扩展作为插件运行到一个单独的进程中,可以在不同的时间运行不同的扩展,所以sharedExtension无论如何都不能正常工作。 - Tom Harrington
肯定有运行时检查吧?我需要这段代码在一个被应用程序和扩展同时使用的扩展中。 - mxcl

4

汤姆的答案是正确的。另一个选择是在您的扩展目标的prefix.pch文件中定义宏,假设您为每个目标使用单独的前缀文件。

#define TODAY_EXTENSION YES

我个人更喜欢这种方法,因为只要在使用宏的地方按住命令键并单击,就可以查看其定义的位置。


1
对于一个Swift项目,您应该将其添加到目标的构建设置中,在Swift编译器 - 自定义标志>活动编译条件下。

enter image description here

更好的是,我将它放在了我的 xcconfig 文件中,以便轻松维护:
SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) iOS_EXTENSION

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