Wie erkennt man, ob Code im Haupt-App- oder App-Erweiterungsziel ausgeführt wird?
-
21-12-2019 - |
Frage
Weiß jemand, wie Sie in Ihrem Code erkennen, ob Sie eine App-Erweiterung ausführen?
Ich habe eine App, die Klassen zwischen einer App und einer Erweiterung teilt.Der App-Code verwendet [UIApplication sharedApplication]
Dies ist jedoch in einer Erweiterung nicht verfügbar, daher wird es nicht kompiliert und sagt:
„sharedApplication“ ist nicht verfügbar:nicht verfügbar iOS (App-Erweiterung)
Ich brauche also eine Möglichkeit, zu erkennen, dass ich mich in der Erweiterung befinde, und eine Alternative dazu zu verwenden sharedApplication
wenn das der Fall ist.
Lösung
Sie können ein Präprozessormakro verwenden:
Verwenden Sie in den Projekteinstellungen das Dropdown-Menü in der oberen Leiste, um Ihr Erweiterungsziel auszuwählen:
Dann:
- Klicken
Build Settings
- Finden (oder suchen)
Preprocessor Macros
unterApple LLVM 6.0 - Preprocessing
- Hinzufügen
TARGET_IS_EXTENSION
oder einen anderen Namen Ihrer Wahl sowohl im Debug- als auch im Release-Bereich.
Dann in Ihrem Code:
#ifndef TARGET_IS_EXTENSION // if it's not defined
// Do your calls to UIApplication
#endif
Andere Tipps
Als Dokumentation von Apple sagt:
Wenn Sie eine Erweiterung basierend auf einer Xcode-Vorlage erstellen, erhalten Sie ein Erweiterungspaket, das auf .appex endet.
Wir können also den folgenden Code verwenden:
if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) {
// this is an app extension
}
Das Präprozessor-Makro funktioniert größtenteils, funktioniert jedoch nicht in gemeinsam genutzten Bibliotheken (z. B.Cocoapods oder gemeinsame Frameworks).
Alternativ können Sie den folgenden Code verwenden.
@implementation ExtensionHelpers
+(BOOL) isAppExtension
{
return [[[NSBundle mainBundle] executablePath] containsString:@".appex/"];
}
@end
Dies funktioniert durch Überprüfen des ausführbaren Pfads des Pakets, da nur die App-Erweiterung die Erweiterung „.appex“ hat.
Sie können dem Erweiterungsziel ein Präprozessormakro hinzufügen und es dann mit a überprüfen #ifdef
innerhalb Ihrer Klasse.
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`
Für meine gemeinsam genutzte Bibliothek habe ich ein separates Ziel erstellt, dessen App-Erweiterungs-Flag auf „Ja“ gesetzt ist, und Präprozessor-Makros in den Build-Einstellungen für dieses bestimmte Ziel verwendet.