sortie - telecharger ios 12




Comment vérifier la version iOS? (20)

Approche préférée

Dans Swift 2.0 Apple a ajouté la vérification de la disponibilité en utilisant une syntaxe beaucoup plus pratique (Lire la suite here ). Maintenant, vous pouvez vérifier la version du système d'exploitation avec une syntaxe plus propre:

if #available(iOS 9, *) {
    // Then we are on iOS 9
} else {
    // iOS 8 or earlier
}

C'est la vérification préférée de respondsToSelector etc ( Quoi de neuf dans Swift ). Maintenant, le compilateur vous avertira toujours si vous ne gardez pas votre code correctement.

Pré Swift 2.0

Nouveau dans iOS 8 est NSProcessInfo permettant de meilleures vérifications de versionnage sémantique.

Déploiement sur iOS 8 et supérieur

Pour les cibles de déploiement minimales d' iOS 8.0 ou supérieur, utilisez NSProcessInfo operatingSystemVersion ou isOperatingSystemAtLeastVersion .

Cela donnerait ce qui suit:

let minimumVersion = NSOperatingSystemVersion(majorVersion: 8, minorVersion: 1, patchVersion: 2)
if NSProcessInfo().isOperatingSystemAtLeastVersion(minimumVersion) {
    //current version is >= (8.1.2)
} else {
    //current version is < (8.1.2)
}

Déploiement sur iOS 7

Pour les cibles de déploiement minimum d' iOS 7.1 ou inférieur, utilisez compare avec NSStringCompareOptions.NumericSearch sur UIDevice systemVersion .

Cela donnerait:

let minimumVersionString = "3.1.3"
let versionComparison = UIDevice.currentDevice().systemVersion.compare(minimumVersionString, options: .NumericSearch)
switch versionComparison {
    case .OrderedSame, .OrderedDescending:
        //current version is >= (3.1.3)
        break
    case .OrderedAscending:
        //current version is < (3.1.3)
        fallthrough
    default:
        break;
}

Plus de lecture à NSHipster .

Je veux vérifier si la version iOS de l'appareil est supérieure à 3.1.3 J'ai essayé des choses comme:

[[UIDevice currentDevice].systemVersion floatValue]

mais ça ne marche pas, je veux juste un:

if (version > 3.1.3) { }

Comment puis-je atteindre cet objectif?


La réponse rapide ...


Depuis Swift 2.0, vous pouvez utiliser #available dans un if ou un guard pour protéger le code qui ne devrait être exécuté que sur certains systèmes.

if #available(iOS 9, *) {}


En Objective-C, vous devez vérifier la version du système et effectuer une comparaison.

[[NSProcessInfo processInfo] operatingSystemVersion] dans iOS 8 et supérieur.

À partir de Xcode 9:

if (@available(iOS 9, *)) {}


La réponse complète ...

En Objective-C, et Swift dans de rares cas, il vaut mieux éviter de s'appuyer sur la version du système d'exploitation pour indiquer les capacités du périphérique ou du système d'exploitation. Il existe généralement une méthode plus fiable pour vérifier si une fonctionnalité ou une classe particulière est disponible.

Vérification de la présence d'API:

Par exemple, vous pouvez vérifier si UIPopoverController est disponible sur le périphérique actuel à l'aide de NSClassFromString :

if (NSClassFromString(@"UIPopoverController")) {
    // Do something
}

Pour les classes faiblement liées, il est possible d'envoyer un message directement à la classe. Notamment, cela fonctionne pour les frameworks qui ne sont pas explicitement liés comme "Required". Pour les classes manquantes, l'expression est nulle, à défaut de la condition suivante:

if ([LAContext class]) {
    // Do something
}

Certaines classes, telles que CLLocationManager et UIDevice , fournissent des méthodes pour vérifier les capacités du périphérique:

if ([CLLocationManager headingAvailable]) {
    // Do something
}

Vérification de la présence de symboles:

Très occasionnellement, vous devez vérifier la présence d'une constante. Cela est venu dans iOS 8 avec l'introduction de UIApplicationOpenSettingsURLString , utilisé pour charger l'application Paramètres via -openURL: La valeur n'existait pas avant iOS 8. Le passage nul à cette API va planter, vous devez donc vérifier l'existence de la constante en premier:

if (&UIApplicationOpenSettingsURLString != NULL) {
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}

Comparaison avec la version du système d'exploitation:

Supposons que vous soyez confronté au besoin relativement rare de vérifier la version du système d'exploitation. Pour les projets ciblant iOS 8 et supérieur, NSProcessInfo inclut une méthode permettant d'effectuer des comparaisons de versions avec moins de risques d'erreur:

- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version

Les projets ciblant les anciens systèmes peuvent utiliser systemVersion sur UIDevice . Apple l'utilise dans son exemple de code GLSprite .

// A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer
// class is used as fallback when it isn't available.
NSString *reqSysVer = @"3.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) {
    displayLinkSupported = TRUE;
}

Si pour une raison quelconque vous décidez que systemVersion est ce que vous voulez, assurez-vous de le traiter comme une chaîne ou vous risquez de tronquer le numéro de révision du patch (par exemple 3.1.2 -> 3.1).


Ceci est utilisé pour vérifier la version du SDK compatible dans Xcode, ceci est si vous avez une grande équipe avec différentes versions de Xcode ou plusieurs projets supportant différents SDK qui partagent le même code:

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
  //programming in iOS 8+ SDK here
#else
  //programming in lower than iOS 8 here   
#endif

Ce que vous voulez vraiment, c'est vérifier la version iOS sur l'appareil. Vous pouvez le faire avec ceci:

if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) {
  //older than iOS 8 code here
} else {
  //iOS 8 specific code here
}

Version rapide:

if let version = Float(UIDevice.current.systemVersion), version < 9.3 {
    //add lower than 9.3 code here
} else {
    //add 9.3 and above code here
}

Comme suggéré par les documents Apple officiels : vous pouvez utiliser NSFoundationVersionNumber , à partir du fichier d'en-tête NSObjCRuntime.h .

if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
    // here you go with iOS 7
}

En général, il est préférable de demander si un objet peut exécuter un sélecteur donné, plutôt que de vérifier un numéro de version pour décider s'il doit être présent.

Lorsque ce n'est pas une option, vous devez être prudent car [@"5.0" compare:@"5" options:NSNumericSearch] renvoie NSOrderedDescending qui peut ne pas être du tout destiné; Je pourrais m'attendre à NSOrderedSame ici. C'est au moins une préoccupation théorique, qui mérite d'être défendue à mon avis.

Il est également intéressant de considérer la possibilité d'une entrée de mauvaise version qui ne peut raisonnablement être comparée à. Apple fournit les trois constantes prédéfinies NSOrderedAscending , NSOrderedSame et NSOrderedDescending mais je peux penser à une utilisation pour quelque chose appelée NSOrderedUnordered dans le cas où je ne peux pas comparer deux choses et je veux retourner une valeur indiquant cela.

De plus, il n'est pas impossible qu'Apple développe un jour ses trois constantes prédéfinies pour permettre une variété de valeurs de retour, en faisant une comparaison != NSOrderedAscending sage.

Cela dit, considérez le code suivant.

typedef enum {kSKOrderedNotOrdered = -2, kSKOrderedAscending = -1, kSKOrderedSame = 0, kSKOrderedDescending = 1} SKComparisonResult;

@interface SKComparator : NSObject
+ (SKComparisonResult)comparePointSeparatedVersionNumber:(NSString *)vOne withPointSeparatedVersionNumber:(NSString *)vTwo;
@end

@implementation SKComparator
+ (SKComparisonResult)comparePointSeparatedVersionNumber:(NSString *)vOne withPointSeparatedVersionNumber:(NSString *)vTwo {
  if (!vOne || !vTwo || [vOne length] < 1 || [vTwo length] < 1 || [vOne rangeOfString:@".."].location != NSNotFound ||
    [vTwo rangeOfString:@".."].location != NSNotFound) {
    return SKOrderedNotOrdered;
  }
  NSCharacterSet *numericalCharSet = [NSCharacterSet characterSetWithCharactersInString:@".0123456789"];
  NSString *vOneTrimmed = [vOne stringByTrimmingCharactersInSet:numericalCharSet];
  NSString *vTwoTrimmed = [vTwo stringByTrimmingCharactersInSet:numericalCharSet];
  if ([vOneTrimmed length] > 0 || [vTwoTrimmed length] > 0) {
    return SKOrderedNotOrdered;
  }
  NSArray *vOneArray = [vOne componentsSeparatedByString:@"."];
  NSArray *vTwoArray = [vTwo componentsSeparatedByString:@"."];
  for (NSUInteger i = 0; i < MIN([vOneArray count], [vTwoArray count]); i++) {
    NSInteger vOneInt = [[vOneArray objectAtIndex:i] intValue];
    NSInteger vTwoInt = [[vTwoArray objectAtIndex:i] intValue];
    if (vOneInt > vTwoInt) {
      return kSKOrderedDescending;
    } else if (vOneInt < vTwoInt) {
      return kSKOrderedAscending;
    }
  }
  if ([vOneArray count] > [vTwoArray count]) {
    for (NSUInteger i = [vTwoArray count]; i < [vOneArray count]; i++) {
      if ([[vOneArray objectAtIndex:i] intValue] > 0) {
        return kSKOrderedDescending;
      }
    }
  } else if ([vOneArray count] < [vTwoArray count]) {
    for (NSUInteger i = [vOneArray count]; i < [vTwoArray count]; i++) {
      if ([[vTwoArray objectAtIndex:i] intValue] > 0) {
        return kSKOrderedAscending;
      }
    }
  }
  return kSKOrderedSame;
}
@end

En tant que variante de la solution yasimturks, j'ai défini une fonction et quelques valeurs enum au lieu de cinq macros. Je trouve ça plus élégant, mais c'est une question de goût.

Usage:

if (systemVersion(LessThan, @"5.0")) ...

Fichier .h:

typedef enum {
  LessThan,
  LessOrEqual,
  Equal,
  GreaterOrEqual,
  GreaterThan,
  NotEqual
} Comparison;

BOOL systemVersion(Comparison test, NSString* version);

fichier .m:

BOOL systemVersion(Comparison test, NSString* version) {
  NSComparisonResult result = [[[UIDevice currentDevice] systemVersion] compare: version options: NSNumericSearch];
  switch (test) {
    case LessThan:       return result == NSOrderedAscending;
    case LessOrEqual:    return result != NSOrderedDescending;
    case Equal:          return result == NSOrderedSame;
    case GreaterOrEqual: return result != NSOrderedAscending;
    case GreaterThan:    return result == NSOrderedDescending;
    case NotEqual:       return result != NSOrderedSame;
  }
}

Vous devez ajouter le préfixe de votre application aux noms, en particulier au type de Comparison .


Essaye ça

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { 
// do some work
}

Essayer:

NSComparisonResult order = [[UIDevice currentDevice].systemVersion compare: @"3.1.3" options: NSNumericSearch];
if (order == NSOrderedSame || order == NSOrderedDescending) {
    // OS version >= 3.1.3
} else {
    // OS version < 3.1.3
}

Exemple rapide qui fonctionne réellement:

switch UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch) {
case .OrderedSame, .OrderedDescending:
    println("iOS >= 8.0")
case .OrderedAscending:
    println("iOS < 8.0")
}

N'utilisez pas NSProcessInfo car il ne fonctionne pas sous 8.0, donc c'est pratiquement inutile jusqu'en 2016


Il existe des versions comme 7.0 ou 6.0.3, donc nous pouvons simplement convertir la version en numérique pour la comparer. Si la version est similaire à la version 7.0, ajoutez simplement un autre ".0" et prenez sa valeur numérique.

 int version;
 NSString* iosVersion=[[UIDevice currentDevice] systemVersion];
 NSArray* components=[iosVersion componentsSeparatedByString:@"."];
 if ([components count]==2) {
    iosVersion=[NSString stringWithFormat:@"%@.0",iosVersion];

 }
 iosVersion=[iosVersion stringByReplacingOccurrencesOfString:@"." withString:@""];
 version=[iosVersion integerValue];

Pour 6.0.0

  if (version==600) {
    // Do something
  }

pour 7.0

 if (version==700) {
   // Do something
 }


Je sais que c'est une vieille question, mais quelqu'un aurait dû mentionner les macros de compilation dans Availability.h . Toutes les autres méthodes ici sont des solutions d'exécution et ne fonctionneront pas dans un fichier d'en-tête, une catégorie de classe ou une définition ivar.

Pour ces situations, utilisez

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_6_0
  // iOS 6+ code here
#else
  // Pre iOS 6 code here
#endif

h / t this réponse


Nouvelle façon de vérifier la version du système en utilisant le raccourci Forget [[UIDevice currentDevice] systemVersion] et NSFoundationVersionNumber.

Nous pouvons utiliser NSProcessInfo -isOperatingSystemAtLeastVersion

     import Foundation

     let yosemite = NSOperatingSystemVersion(majorVersion: 10, minorVersion: 10, patchVersion: 0)
     NSProcessInfo().isOperatingSystemAtLeastVersion(yosemite) // false

Une version plus générique dans Obj-C ++ 11 (vous pourriez probablement remplacer certains de ces trucs par les fonctions NSString / C, mais ceci est moins verbeux.) Cela vous donne deux mécanismes: splitSystemVersion vous donne un tableau de toutes les parties qui est utile si vous voulez simplement activer la version majeure (par exemple switch([self splitSystemVersion][0]) {case 4: break; case 5: break; } ).

#include <boost/lexical_cast.hpp>

- (std::vector<int>) splitSystemVersion {
    std::string version = [[[UIDevice currentDevice] systemVersion] UTF8String];
    std::vector<int> versions;
    auto i = version.begin();

    while (i != version.end()) {
        auto nextIllegalChar = std::find_if(i, version.end(), [] (char c) -> bool { return !isdigit(c); } );
        std::string versionPart(i, nextIllegalChar);
        i = std::find_if(nextIllegalChar, version.end(), isdigit);

        versions.push_back(boost::lexical_cast<int>(versionPart));
    }

    return versions;
}

/** Losslessly parse system version into a number
 * @return <0>: the version as a number,
 * @return <1>: how many numeric parts went into the composed number. e.g.
 * X.Y.Z = 3.  You need this to know how to compare again <0>
 */
- (std::tuple<int, int>) parseSystemVersion {
    std::string version = [[[UIDevice currentDevice] systemVersion] UTF8String];
    int versionAsNumber = 0;
    int nParts = 0;

    auto i = version.begin();
    while (i != version.end()) {
        auto nextIllegalChar = std::find_if(i, version.end(), [] (char c) -> bool { return !isdigit(c); } );
        std::string versionPart(i, nextIllegalChar);
        i = std::find_if(nextIllegalChar, version.end(), isdigit);

        int part = (boost::lexical_cast<int>(versionPart));
        versionAsNumber = versionAsNumber * 100 + part;
        nParts ++;
    }

    return {versionAsNumber, nParts};
}


/** Assume that the system version will not go beyond X.Y.Z.W format.
 * @return The version string.
 */
- (int) parseSystemVersionAlt {
    std::string version = [[[UIDevice currentDevice] systemVersion] UTF8String];
    int versionAsNumber = 0;
    int nParts = 0;

    auto i = version.begin();
    while (i != version.end() && nParts < 4) {
        auto nextIllegalChar = std::find_if(i, version.end(), [] (char c) -> bool { return !isdigit(c); } );
        std::string versionPart(i, nextIllegalChar);
        i = std::find_if(nextIllegalChar, version.end(), isdigit);

        int part = (boost::lexical_cast<int>(versionPart));
        versionAsNumber = versionAsNumber * 100 + part;
        nParts ++;
    }

    // don't forget to pad as systemVersion may have less parts (i.e. X.Y).
    for (; nParts < 4; nParts++) {
        versionAsNumber *= 100;
    }

    return versionAsNumber;
}

Solution pour vérifier la version iOS dans Swift

switch (UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch)) {
    case .OrderedAscending:
       println("iOS < 8.0")

    case .OrderedSame, .OrderedDescending:
       println("iOS >= 8.0")
}

Con of this solution: it is simply bad practice to check against OS version numbers, whichever way you do it. One should never hard code dependencies in this way, always check for features, capabilities or the existence of a class. Consider this; Apple may release a backwards compatible version of a class, if they did then the code you suggest would never use it as your logic looks for an OS version number and NOT the existence of the class.

( NSHipster )

Solution for checking the class existence in Swift

if (objc_getClass("UIAlertController") == nil) {
   // iOS 7
} else {
   // iOS 8+
}

Do not use if (NSClassFromString("UIAlertController") == nil) because it works correctly on the iOS simulator using iOS 7.1 and 8.2, but if you test on a real device using iOS 7.1, you will unfortunately notice that you will never pass through the else part of the code snippet.


UIDevice + IOSVersion.h

@interface UIDevice (IOSVersion)

+ (BOOL)isCurrentIOSVersionEqualToVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionGreaterThanVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionGreaterThanOrEqualToVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionLessThanVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionLessThanOrEqualToVersion:(NSString *)iOSVersion

@end

UIDevice + IOSVersion.m

#import "UIDevice+IOSVersion.h"

@implementation UIDevice (IOSVersion)

+ (BOOL)isCurrentIOSVersionEqualToVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] == NSOrderedSame;
}

+ (BOOL)isCurrentIOSVersionGreaterThanVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] == NSOrderedDescending;
}

+ (BOOL)isCurrentIOSVersionGreaterThanOrEqualToVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] != NSOrderedAscending;
}

+ (BOOL)isCurrentIOSVersionLessThanVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] == NSOrderedAscending;
}

+ (BOOL)isCurrentIOSVersionLessThanOrEqualToVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] != NSOrderedDescending;
}

@end

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

Puis ajoutez une condition if comme suit: -

if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) {
   //Your code
}       

#define _kisiOS7 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)

if (_kisiOS7) {
            NSLog(@"iOS7 or greater")
} 
else {
           NSLog(@"Less than iOS7");
}

/*
 *  System Versioning Preprocessor Macros
 */ 

#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

/*
 *  Usage
 */ 

if (SYSTEM_VERSION_LESS_THAN(@"4.0")) {
    ...
}

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"3.1.1")) {
    ...
}

float deviceOSVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
float versionToBeCompared = 3.1.3; //(For Example in your case)

if(deviceOSVersion < versionToBeCompared)
   //Do whatever you need to do. Device version is lesser than 3.1.3(in your case)
else 
   //Device version should be either equal to the version you specified or above




objective-c