web-dev-qa-db-fra.com

Comment détecter si du code est en cours d'exécution dans l'application principale ou dans la cible de l'extension d'application?

Est-ce que quelqu'un sait comment vous détectez depuis votre code si vous utilisez une extension d'application?

J'ai une application qui partage les classes entre une application et une extension. Le code de l'application utilise [UIApplication sharedApplication], mais ceci n'est pas disponible dans une extension, donc il ne compilera pas en disant:

'sharedApplication' n'est pas disponible: non disponible iOS (App Extension)

J'ai donc besoin d'un moyen de détecter que je suis dans l'extension et d'utiliser une alternative à sharedApplication si c'est le cas.

27
Mark Bridges

Vous pouvez utiliser une macro de préprocesseur:

Dans les paramètres du projet, utilisez la liste déroulante située dans la barre supérieure pour sélectionner votre cible d’extension: enter image description here

Ensuite:

  1. Cliquez sur Build Settings 
  2. Recherchez (ou recherchez) Preprocessor Macros sous Apple LLVM 6.0 - Preprocessing
  3. Ajoutez TARGET_IS_EXTENSION ou tout autre nom de votre choix dans les sections debug et release.

Puis dans votre code:

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

Comme la documentation d'Apple dit:

Lorsque vous créez une extension basée sur un modèle Xcode, vous obtenez un ensemble d'extension se terminant par .appex.

Nous pouvons donc utiliser le code suivant:

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

La macro de préprocesseur fonctionnera principalement, mais ne fonctionnera pas dans une bibliothèque partagée (par exemple, des cocoapodes ou des cadres partagés). 

Sinon, vous pouvez utiliser le code suivant. 

@implementation ExtensionHelpers

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

@end

Cela fonctionne en vérifiant le chemin executablePath de l'ensemble, car seule l'extension d'application possède l'extension ".appex".

23
siuying

Vous pouvez ajouter une macro de préprocesseur sur la cible d'extension, puis vérifier avec un #ifdef à l'intérieur de votre classe.

2
Marcelo Fabri

Pour ma bibliothèque partagée, j'ai créé un indicateur de cible distinct dont les extensions d'application sont définies sur Oui, et utilisé des macros de préprocesseur dans les paramètres de construction de cette cible spécifique.

0
cohen72