How to detect if code is running in Main App or App Extension Target?

牧云@^-^@ 提交于 2020-02-12 07:28:06

问题


Does anyone know how you detect from within your code if you're running inside an App Extension?

I have an app which shares classes between an app and an extension. The app code uses [UIApplication sharedApplication] but this isn't available from within an extension, so it won't compile saying:

'sharedApplication' is unavailable: not available iOS (App Extension)

So I need a way to detect that I'm in the extension and use an alternative to sharedApplication if that's the case.


回答1:


You can use a preprocessor macro:

In the project settings use the dropdown in the topbar to select your extension target:

Then:

  1. Click Build Settings
  2. Find (or search) Preprocessor Macros under Apple LLVM 6.0 - Preprocessing
  3. Add TARGET_IS_EXTENSION or any other name of your choice in both the debug and release sections.

Then in your code:

#ifndef TARGET_IS_EXTENSION // if it's not defined
    // Do your calls to UIApplication
#endif



回答2:


As Apple's documentation says:

When you build an extension based on an Xcode template, you get an extension bundle that ends in .appex.

So, we can use the following code:

if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) {
    // this is an app extension
}



回答3:


The preprocessor macro will work mostly, but will not work in shared library (e.g. cocoapods or shared frameworks).

Alternatively you can use following code.

@implementation ExtensionHelpers

+(BOOL) isAppExtension
{
    return [[[NSBundle mainBundle] executablePath] containsString:@".appex/"];
}

@end

This work by checking the bundle executablePath, as only App Extension has extension ".appex".




回答4:


You can add a preprocessor macro on the extension target and then check with a #ifdef inside of your class.




回答5:


Swift 5

let bundleUrl: URL = Bundle.main.bundleURL
let bundlePathExtension: String = bundleUrl.pathExtension
let isAppex: Bool = bundlePathExtension == "appex"

// `true` when invoked inside the `Extension process`
// `false` when invoked inside the `Main process`



回答6:


For my shared library I created a separate target who's app extensions flag is set to yes, and used preprocessor macro's within the build settings for that specific target.



来源:https://stackoverflow.com/questions/25048026/how-to-detect-if-code-is-running-in-main-app-or-app-extension-target

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!