アプリ拡張機能の内部で実行している場合、コード内からどのように検出するか誰かが知っていますか?
アプリと拡張機能の間でクラスを共有するアプリがあります。アプリのコードは[UIApplication sharedApplication]
ただし、これは拡張機能内からは使用できないため、次のようにコンパイルされません。
'sharedApplication'は利用できません:iOS(App Extension)は利用できません
そのため、私が拡張機能にいることを検出し、sharedApplication
の代わりに使用する方法が必要です。
プリプロセッサマクロを使用できます。
プロジェクト設定で、トップバーのドロップダウンを使用して拡張ターゲットを選択します。
次に:
Build Settings
をクリックしますPreprocessor Macros
の下にあるApple LLVM 6.0 - Preprocessing
を検索(または検索)します- デバッグセクションとリリースセクションの両方に
TARGET_IS_EXTENSION
またはその他の任意の名前を追加します。
次に、コードで:
#ifndef TARGET_IS_EXTENSION // if it's not defined
// Do your calls to UIApplication
#endif
として アップルのドキュメント は言う:
Xcodeテンプレートに基づいて拡張機能を作成すると、.appexで終わる拡張バンドルが作成されます。
したがって、次のコードを使用できます。
if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) {
// this is an app extension
}
プリプロセッサマクロはほとんど機能しますが、共有ライブラリ(例:cocoapodsまたは共有フレームワーク)では機能しません。
または、次のコードを使用できます。
@implementation ExtensionHelpers
+(BOOL) isAppExtension
{
return [[[NSBundle mainBundle] executablePath] containsString:@".appex/"];
}
@end
App Extensionのみが拡張子「.appex」を持つため、これはバンドルのexecutablePathをチェックすることで機能します。
拡張ターゲットにプリプロセッサマクロを追加して、#ifdef
クラス内。
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`
私の共有ライブラリでは、アプリ拡張フラグがyesに設定されている別のターゲットを作成し、その特定のターゲットのビルド設定内でプリプロセッサマクロを使用しました。