什么是预处理器macros来testing是否正在构build应用程序扩展?

这个问题完全基于公开发布的关于在iOS中引入应用程序扩展的文档。

随着在iOS 8中引入应用程序扩展 ,现在可以“扩展定制function和内容,超越您的应用程序,并在用户使用其他应用程序时提供给用户”。

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

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

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

 #if TARGET_IPHONE_SIMULATOR // Code Here #endif 

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

你可以定义你自己的macros。

在项目设置中,使用顶栏的下拉菜单select您的扩展目标: 在这里输入图像说明

然后:

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

然后在你的代码中:

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

您可以使用与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)方式工作。 伤心。

这实际上并没有被问到,但应该指出:

如果你正在使用Swift,你有@available(iOSApplicationExtension)属性! 这实际上并不是预处理器的特性,但它是一种编译时特性。

例:

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

或者用#注释 ( 但可能不是 ):

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