web-dev-qa-db-ja.com

コードがメインアプリまたはアプリ拡張ターゲットで実行されているかどうかを検出する方法

アプリ拡張機能の内部で実行している場合、コード内からどのように検出するか誰かが知っていますか?

アプリと拡張機能の間でクラスを共有するアプリがあります。アプリのコードは[UIApplication sharedApplication]ただし、これは拡張機能内からは使用できないため、次のようにコンパイルされません。

'sharedApplication'は利用できません:iOS(App Extension)は利用できません

そのため、私が拡張機能にいることを検出し、sharedApplicationの代わりに使用する方法が必要です。

33
Mark Bridges

プリプロセッサマクロを使用できます。

プロジェクト設定で、トップバーのドロップダウンを使用して拡張ターゲットを選択します。 enter image description here

次に:

  1. Build Settingsをクリックします
  2. Preprocessor Macrosの下にあるApple LLVM 6.0 - Preprocessingを検索(または検索)します
  3. デバッグセクションとリリースセクションの両方にTARGET_IS_EXTENSIONまたはその他の任意の名前を追加します。

次に、コードで:

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

として アップルのドキュメント は言う:

Xcodeテンプレートに基づいて拡張機能を作成すると、.appexで終わる拡張バンドルが作成されます。

したがって、次のコードを使用できます。

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

プリプロセッサマクロはほとんど機能しますが、共有ライブラリ(例:cocoapodsまたは共有フレームワーク)では機能しません。

または、次のコードを使用できます。

@implementation ExtensionHelpers

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

@end

App Extensionのみが拡張子「.appex」を持つため、これはバンドルのexecutablePathをチェックすることで機能します。

23
siuying

拡張ターゲットにプリプロセッサマクロを追加して、#ifdefクラス内。

2
Marcelo Fabri

スウィフト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`
0
neoneye

私の共有ライブラリでは、アプリ拡張フラグがyesに設定されている別のターゲットを作成し、その特定のターゲットのビルド設定内でプリプロセッサマクロを使用しました。

0
cohen72