In Swift, how to ignore a part of the code when running from an App Extension target?

Viewed 673

There's a similar question that works on Objective-C, but I tried the same code in Swift and it never executes, neither in the main app, nor in the action extension.

My situation is similar to the one in the question above, that is, when running from the main app I want to use UIApplication.shared.open to open a link in Safari, but I want to ignore this part of the code on the App Extension.

The problem isn't finding out whether the app is running from an App Extension or not, but ignoring the code when building for the App Extension, so that the compiler does not give me the following error on build:

enter image description here

2 Answers

You could introduce a new Custom Flag (similar to the DEBUG flag) for the extension target. In your Build Settings look for the Custom Flags and add a new one (e.g. "EXTENSION"). Like here in the screenshot, but also do it for release. Extension Configuration

In your Code you could then do something like

#if EXTENSION
    // here goes code that is only compiled in the extension
#else 
    // here goes code that is only compiled outside the extension 
#endif

Update: Please read the Apple provided documentation on App Extensions:

Some APIs Are Unavailable to App Extensions

Because of its focused role in the system, an app extension is ineligible to participate in certain activities. An app extension cannot:

  • Access a Application.shared object, and so cannot use any of the methods on that object

- Apple, App Extension Programming Guide

To programmatically find if the it the running extension via code it's really simple, just do this:

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`
Related