web-dev-qa-db-fra.com

Macro de préprocesseur Xcode pour vérifier si Base SDK> = iOS 7.0

Existe-t-il une macro de préprocesseur pour compiler certaines parties de code uniquement si le SDK de base est 7.0 ou supérieur? La constante définie "__IPHONE_7_0" semble être liée à la cible de développement iOS (et non au SDK de base).

J'utilise XCode 5 avec iOS 7 et iOS 6.1 installés.

La raison pour laquelle je pose cette question est que je suis en train de faire la transition d'une application d'iOS 6 vers iOS 7. Il y a pas mal de choses à régler, et j'aimerais toujours compiler mon application avec iOS 6.1 comme SDK de base (et avec la cible de développement iOS 6.0), mais j'aimerais déjà ajouter du code que je souhaiterai chaque fois que je compile avec le SDK iOS 7, mais qui ne compile pas si le SDK de base est iOS 6.1.

Exemple:

if ([_tableView respondsToSelector:@selector(setSeparatorInset:)]) {
    [_tableView setSeparatorInset:UIEdgeInsetsZero];
}

Ce morceau de code ci-dessus ne se compile pas avec le SDK de base iOS 6.1, car il se plaint que setSeparatorInset ne soit pas défini pour UITableView. Par conséquent, je voudrais inclure ce morceau de code dans une directive de préprocesseur, conditionnellement sur le SDK de base.

32
quentinadam

Vous devriez lire Apple Guide de compatibilité du SDK où toutes ces techniques sont expliquées.

En particulier, ils recommandent d'utiliser le __IPHONE_OS_VERSION_MIN_REQUIRED macro pour tester la cible de déploiement de votre projet (version minimale prise en charge), et pour votre cas utiliser le __IPHONE_OS_VERSION_MAX_ALLOWED macro pour tester le SDK de base utilisé pour la compilation .


Exemple:

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
// Only COMPILE this if compiled against BaseSDK iOS7.0 or greater
if ([_tableView respondsToSelector:@selector(setSeparatorInset:)]) {
   // Even when compiled with BaseSDK 7, only EXECUTE that if the user uses an
   // OS that support this method (namely if the user is running iOS7 or later,
   // but not for users running iOS6).
   [_tableView setSeparatorInset:UIEdgeInsetsZero];
}
#endif

Remarque importante: vous devez utiliser des constantes numériques dans votre comparaison comme si vous testiez #if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_7_0 par exemple, cela ne fonctionnera pas lors de l'utilisation du SDK 6, comme __IPHONE_7_0 n'est pas défini, donc évalué à 0 dans ce contexte et votre condition ne fonctionnera pas comme prévu.

43
AliSoftware

Oui, vous pouvez utiliser le __IPHONE_7_0 définir:

#ifdef __IPHONE_7_0
    if ([_tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [_tableView setSeparatorInset:UIEdgeInsetsZero];
    }
#endif
20
rckoenes

Conformément à Apple Doc, vous devez utiliser NSFoundationVersionNumber pour faire la distinction entre iOS 7 et les autres. Vous pouvez le simplifier en utilisant les macros suivantes:

#define isIOS6 floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1 
#define isIOS7 floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1

puis plus tard dans le code faire

#ifdef __IPHONE_7_0
    if (isIOS7) {
       // Do additional stuff for iOS 7.
    } 
#endif

Oui, vous devez vérifier à la fois au moment de la compilation (avec #ifdef) Et au moment de l'exécution (avec isIOS7) De cette façon, vous pourrez compiler avec le SDK iOS6, le SDK iOS7 et également le SDK iOS7 avec une cible iOS6.

OH! N'oubliez pas que vous ne pouvez pas faire if (!isIOS7) vous devez utiliser if (isIOS6).

https://developer.Apple.com/library/ios/documentation/userexperience/conceptual/transitionguide/

12
Mojtaba

Vous pouvez également utiliser cette macro

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:(v) options:NSNumericSearch] != NSOrderedAscending)

par exemple if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.1")) {[self doSomething];} else {[self doSomethingElse];}

3
Akki

Vous ne devriez pas tester le sdk mais la disponibilité de la méthode/classe IMHO. Donc pas du tout précompilé

2
Daij-Djan