【问题标题】:What is the preprocessor macro to test whether an application extension is being built?测试是否正在构建应用程序扩展的预处理器宏是什么?
【发布时间】:2014-07-23 23:29:06
【问题描述】:

此问题纯粹基于公开发布的有关在 iOS 中引入应用程序扩展的文档。

随着 iOS 8 中 app extensions 的引入,现在可以“将自定义功能和内容扩展到您的应用之外,并在用户使用其他应用时提供给用户”。

在我的扩展程序的实现中,我在我的扩展程序(模型等)中包含了一些来自我的实际应用程序的类。问题是这些类调用UIApplication,这在应用程序扩展中不可用,编译器告诉我。

我认为一个简单的解决方案是将任何对 UIApplication 的调用包含在 #if 指令中。

例如,如果我只想包含在模拟器上运行的代码,我会使用:

#if TARGET_IPHONE_SIMULATOR
    // Code Here
#endif

当目标是应用程序扩展时,是否有类似定义的宏?

【问题讨论】:

  • 似乎NS_EXTENSION_UNAVAILABLE 可能会有所帮助,但我不知道如何使用它。

标签: ios preprocessor ios8 ios-app-extension


【解决方案1】:

您可以定义自己的宏。

在项目设置中,使用顶部栏中的下拉菜单选择您的扩展目标:

然后:

  1. 点击Build Settings
  2. Apple LLVM 6.0 - Preprocessing 下查找(或搜索)Preprocessor Macros
  3. 在调试和发布部分添加 TARGET_IS_EXTENSION 或您选择的任何其他名称。

然后在你的代码中:

#ifndef TARGET_IS_EXTENSION
    // Do your calls to UIApplication
#endif

【讨论】:

  • 它有效 :) ,但我想我不明白,这个条件是否意味着如果您构建扩展目标应该“不要调用 UIApplications”或者我错过了什么?
  • 我相信你是对的@MohamedSaleh,我的错。
  • 没问题,这里的重点是它实际上按照您的建议工作,而不是相反:D,我真的不知道为什么?!
  • 因为#ifndef 表示“如果未定义”。所以你只在运行 // 如果 TARGET_IS_EXTENSION 未定义,则调用 UIApplication 代码,这将在主应用程序上,而不是在扩展程序上
【解决方案2】:

您可以使用与 Apple 相同的技术来引发编译错误。

#if !(defined(__has_feature) && __has_feature(attribute_availability_app_extension))
  //Not in the extension
#else
  //In extension
#end

【讨论】:

  • 您必须按照接受的答案中的说明定义自己的宏。您可以如上所述在项目设置中定义它,也可以将其添加到扩展的前缀头文件中。你不能使用__has_feature(attribute_availability_app_extension)。该宏仅检查您使用的编译器是否支持构建应用程序扩展,而不是您当前是否正在构建一个。即使您正在构建您的主应用程序,在较新的 Xcode(6.2+)上也将始终如此。我想确保这一点很清楚,所以没有其他人发现这个问题错误地使用了宏。
【解决方案3】:

更新:不幸的是,它实际上并没有工作,因为它以__has_feature(attribute_availability_app_extension)-feature 方式工作。伤心。

实际上并没有被问到,但应该注意:

如果你使用的是 Swift,你有 @available(iOSApplicationExtension) 属性!它实际上不是预处理器的功能,而是一种编译时功能。

例子:

@available(iOSApplicationExtension, message="It is meaningless outside keyboard extension")
public var rootInputViewController: UIInputViewController {
    return storedInputViewController
}

或使用 #-notation (but probably not):

public static var rootInputViewController: UIInputViewController! {
    guard #available(iOSApplicationExtension 8, *) else {
        return nil
    }

    return storedInputViewController!
}

【讨论】:

  • 这是不正确的。 #available(iOSApplicationExtension 8, *) 将适用于在 iOS8+ 和 所有其他 上的扩展中运行的代码,包括适用于所有版本的 iOS 应用程序本身。换句话说,它仅适用于 iOS 版本早于 8 的扩展。不幸的是,由于 lats 参数中的 *,#available 只能用于剥离平台的旧版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-04
  • 1970-01-01
  • 2014-11-23
  • 2016-05-09
  • 2019-12-05
  • 2020-10-18
相关资源
最近更新 更多