Vérification de la compilation conditionnelle du framework avant importation

Je cherche un moyen de vérifier si un framework existe et / ou si ses classes sont définies avant d’importer et d’utiliser ce framework. Plus précisément, le cadre est Assets Library.

Actuellement, je suis capable de faire cela avec la structure Core Data, car cette structure contient un fichier appelé CoreDataDefines.h qui fournit une directive de pré-traitement _COREDATADEFINES_H. Cela me permet de vérifier simplement pour cette définition comme suit:

#ifdef _COREDATADEFINES_H #import  // do something with Core Data #else // do something without using Core Data #endif 

Malheureusement, Assets Library ne fournit pas de fichier d’en-tête de définitions clair. Je cherche donc un moyen d’écrire ma propre instruction #define permettant de vérifier l’existence du cadre avant de l’importer, comme je l’ai fait pour Core Data ci-dessus.

J’ai essayé ceci:

 #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000 // import assets library if defined ! #define ASSETSLIBRARY_DEFINE (NSClassFromSsortingng(@"ALAsset") != nil) #if ASSETSLIBRARY_DEFINE #import  #endif #endif 

… mais pas de chance.
Le compilateur me dit que le “jeton n’est pas un opérateur binary valide dans une sous-expression du préprocesseur”.

Toute aide est toujours très appréciée.

Si vous savez quelle classe doit être imscope avec le framework, vous pouvez vérifier si elle est chargée:

 BOOL isFrameworkLoaded = (NSClassFromSsortingng(@"MyClassNameFromTheFramework") != nil); 

Ce que vous faites ici est très faux. La définition de _COREDATADEFINES_H vous voyez dans CoreDataDefines.h est connue sous le nom de valeur indicative, une ancienne technique en C permettant d’éviter plusieurs inclusions du même fichier d’en-tête.

Vous ne devriez certainement pas utiliser cela dans votre propre code, et la présence du sentinal vous indique seulement que l’en-tête a déjà été inclus ailleurs. Si la sentinelle n’est pas définie, cela signifie simplement que l’en-tête n’a pas été inclus, mais pas que le cadre lui-même est inexistant.

Je ne sais pas exactement ce que vous essayez de faire, mais il semblerait que vous souhaitiez utiliser des macros pour choisir entre un code qui utilise le framework et un code qui n’utilise pas le framework. Si vous voulez le faire au moment de la compilation, votre seul choix est de définir vos propres macros et de les configurer dans votre cible avec certaines options du compilateur. Par exemple, pour activer le code qui utilise la bibliothèque d’actifs, vous pouvez le définir dans le paramètre de construction “Autres indicateurs C”:

 -DUSE_ASSETS_FRAMEWORK 

Et puis utilisez ceci dans votre code:

 #ifdef USE_ASSETS_FRAMEWORK #import  // code that uses assets framework #else // code that does not use assets framework #endif 

Si vous souhaitez pouvoir détecter au moment de l’exécution si l’application est liée au framework et que celui-ci existe dans la version iOS actuelle, vous devez utiliser l’approche standard recommandée par Apple, à savoir tester l’existence de classes ou de fonctions que vous utilisez. avoir besoin:

 if (NSClassFromSsortingng(@"ALAsset")) { // ALAsset is available } } else { // ALAsset not available } 

J’ai quelques astuces pour ce genre de choses… Bien que ce qui suit ne résoudra PAS EXACTEMENT les problèmes que vous avez décrits, cela pourrait vous aider à trouver votre solution ultime… La première «stratégie» peut être appelée dans une «phase de construction du script». Cela peut être utilisé de différentes manières, mais dans cet exemple, il vérifie que le Framework est valide (selon otool , puis effectue un “post-traitement” en conséquence .. et le teste à nouveau .. et ainsi de suite ..

 function test { "$@"; status=$?; if [ $status -ne 0 ]; then echo "error with $1"; fi return $status } PRODUCT_PATH="${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}" BINARY="$PRODUCT_PATH/${PRODUCT_NAME}" MAC="/Library/Frameworks/" SYSTEM_PRODUCT="$MAC/${WRAPPER_NAME}" test otool -l "$BINARY" #/Library/Frameworks/AtoZ.framework/AtoZ if [ $status -ne 0 ]; then sudo rm -r "$SYSTEM_PRODUCT" sudo cp -r "$PRODUCT_PATH" "$SYSTEM_PRODUCT" test otool -l "$BINARY" if [ $status == 0 ]; then cd "${PRODUCT_PATH}" ln -sF Versions/Current/Frameworks Frameworks fi 

La prochaine main dans cette sagesse libre-pour-tout est la méthode sexy et bien nommée NSBundle .. NSBundle

 NSBundle *b = [NSBundle bundleWithPath:path]; NSError *e = nil; BOOL okdok = [b preflightAndReturnError:&e]; if (okdok) okdok = [b load]; if (!okdok) { [self jumpOffABridge:nil]; goto hell; } 

Les chances sont cependant … vous serez .. OK DOK , à la fin du load .