Come rilevare se il codice è in esecuzione nell'app principale o nell'obiettivo dell'estensione dell'app?
-
21-12-2019 - |
Domanda
Qualcuno sa come si rileva all'interno del tuo codice se stai utilizzando un'estensione di app?
Ho un'app che condivide le classi tra un'app e un'estensione.Il codice dell'app utilizza [UIApplication sharedApplication]
ma questo non è disponibile da un'estensione, quindi non si compilerà dicendo:
.'sharedApplication' non è disponibile: non disponibile iOS (estensione app)
Quindi ho bisogno di un modo per rilevare che sono nell'estensione e usi un'alternativa a sharedApplication
se è così.
Soluzione
È possibile utilizzare una macro preprocessore:
Nelle impostazioni del progetto Utilizzare il menu a discesa nella TopBar per selezionare il target di estensione:
Allora:
..
- Fai clic su
Build Settings
- Trova (o ricerca)
Preprocessor Macros
sottoApple LLVM 6.0 - Preprocessing
- Aggiungi
TARGET_IS_EXTENSION
o qualsiasi altro nome di tua scelta sia nelle sezioni di debug che di rilascio.
Allora nel tuo codice:
#ifndef TARGET_IS_EXTENSION // if it's not defined
// Do your calls to UIApplication
#endif
. Altri suggerimenti
come Documentazione di Apple dice: .
.Quando si crea un'estensione basata su un modello Xcode, ottieni un pacchetto di estensione che termina in .AppEX.
Quindi, possiamo usare il seguente codice:
if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) {
// this is an app extension
}
. La macro preprocessore funzionerà principalmente, ma non funzionerà in Biblioteca condivisa (ad esempio cacapodi o quadri condivisi).
In alternativa è possibile utilizzare il seguente codice.
@implementation ExtensionHelpers
+(BOOL) isAppExtension
{
return [[[NSBundle mainBundle] executablePath] containsString:@".appex/"];
}
@end
.
Questo lavoro controllando il pacchetto eseguibilePath, poiché solo l'estensione dell'app ha un'estensione ".AppEX".
È possibile aggiungere una macro preprocessore sul bersaglio dell'estensione e quindi controllare con un #ifdef
all'interno della tua classe.
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`
. Per la mia biblioteca condivisa ho creato un bersaglio separato che è il flag di estensioni dell'app è impostato su Sì, e utilizzato la macro di preprocessore all'interno delle impostazioni di build per quel target specifico.