Ios 如何检测代码是否在主应用程序或应用程序扩展目标中运行?
如果你在应用程序扩展中运行,有人知道你是如何从代码中检测的吗 我有一个在应用程序和扩展程序之间共享类的应用程序。应用程序代码使用Ios 如何检测代码是否在主应用程序或应用程序扩展目标中运行?,ios,uiapplicationdelegate,ios-app-extension,Ios,Uiapplicationdelegate,Ios App Extension,如果你在应用程序扩展中运行,有人知道你是如何从代码中检测的吗 我有一个在应用程序和扩展程序之间共享类的应用程序。应用程序代码使用[UIApplication sharedApplication],但这在扩展中不可用,因此它不会编译为: “sharedApplication”不可用:iOS(应用程序扩展)不可用 因此,我需要一种方法来检测我是否在扩展中,并在这种情况下使用一种替代方法来替代sharedApplication。您可以在扩展目标上添加一个预处理器宏,然后在类中使用\ifdef进行检查。
[UIApplication sharedApplication]
,但这在扩展中不可用,因此它不会编译为:
“sharedApplication”不可用:iOS(应用程序扩展)不可用
因此,我需要一种方法来检测我是否在扩展中,并在这种情况下使用一种替代方法来替代
sharedApplication
。您可以在扩展目标上添加一个预处理器宏,然后在类中使用\ifdef
进行检查。您可以使用预处理器宏:
在“项目设置”中,使用顶部栏中的下拉列表选择扩展目标:
然后:
预处理器宏
TARGET\u是\u扩展名或您选择的任何其他名称
#ifndef TARGET_IS_EXTENSION // if it's not defined
// Do your calls to UIApplication
#endif
预处理器宏将主要工作,但不会在共享库(例如CoCoapod或共享框架)中工作 或者,您可以使用以下代码
@implementation ExtensionHelpers
+(BOOL) isAppExtension
{
return [[[NSBundle mainBundle] executablePath] containsString:@".appex/"];
}
@end
这是通过检查bundle executablePath来实现的,因为只有应用程序扩展具有扩展名“.appex”。对于我的共享库,我创建了一个单独的目标,该目标的应用程序扩展标志设置为“是”,并在该特定目标的构建设置中使用预处理器宏。如所述: 在基于Xcode模板构建扩展时,会得到一个以.appex结尾的扩展包 因此,我们可以使用以下代码:
if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) {
// this is an app extension
}
// Swift version
if Bundle.main.bundlePath.hasSuffix(".appex") {
// this is an app extension
}
斯威夫特5
圣诞老人提出的解决办法对我不起作用 起作用的是:
#if EXTENSION
// IF is extension (SIRI) we do stuff
#else
// ELSE is main app do more stuff
#endif
谢谢,这种方法是有效的,但事实上,我需要用另一种方法来检测。如果不是扩展,请使用UIApplication。无论如何,我在应用程序目标生成设置中用一个标志解决了这个问题,将它标识为应用程序,而不是扩展。@MarkBridges对此表示抱歉。我在给未来读者的回答中修正了这个问题。这个解决方案不适用于框架中的代码。我们目前正在检查应用程序包的名称,以查看代码是否在扩展中运行,但我希望找到更好的方法。请描述您的代码。我也面临同样的问题,我需要添加什么标志或代码,然后应用程序将根据应用程序或扩展选择。记住,我创建了共享框架,这些代码应该基于bundle id执行。我的代码流似乎根本没有进入ifdef。知道为什么吗?我在编译共享库时仍然会遇到编译错误,因为它的“仅需要应用程序扩展安全API”标志设置为“是”。在仍然使用上面编写的代码时,如何避免编译错误?我不建议在生产环境中使用-[NSString containsString:],原因有二:1。它没有发布API,即官方帮助页面没有提到它(这可能是一个bug,但无论如何);2.它将在iOS7上崩溃。改为使用-[NSString rangeOfString:]。@AlexanderVasenin 2:它记录在NSString.h中,并清楚地标记为在iOS 8+上可用。请检查此线程。还有一个没有预处理器宏的解决方案宏这应该是选定的答案,这比依赖预处理器宏要好得多。同意,这更干净。不是真正干净,它是间接的,如果扩展发生变化,它可能在将来发生变化,加上条件编译将允许您排除无法在扩展中编译的资源或方法。这太完美了!谢谢:)
#if EXTENSION
// IF is extension (SIRI) we do stuff
#else
// ELSE is main app do more stuff
#endif