89 votes

comparer les numéros de version en objective-c

je suis en train d'écrire une application qui reçoit les données avec les éléments et les numéros de version. Les chiffres sont formatés comme 1.0.1 ou 1.2.5. Comment puis-je comparer ces numéros de version. Je pense qu'ils doivent être formatés comme une chaîne de caractères en premier, non? Si oui, quelle option dois-je avoir pour objectif C comprendre la 1.2.5 est plus récente que la version 1.0.1?

246voto

Nathan de Vries Points 10895

C'est la façon la plus simple de comparer les versions, en gardant à l'esprit que "1" < "1.0" < "1.0.0":

NSString* requiredVersion = @"1.2.0";
NSString* actualVersion = @"1.1.5";

if ([requiredVersion compare:actualVersion options:NSNumericSearch] == NSOrderedDescending) {
  // actualVersion is lower than the requiredVersion
}

17voto

nikkiauburger Points 71

Je vais ajouter ma méthode, ce qui se compare strictement numérique versions (pas de a, b, RC etc.) avec un nombre quelconque de composants.

+ (NSComparisonResult)compareVersion:(NSString*)versionOne toVersion:(NSString*)versionTwo {
    NSArray* versionOneComp = [versionOne componentsSeparatedByString:@"."];
    NSArray* versionTwoComp = [versionTwo componentsSeparatedByString:@"."];

    NSInteger pos = 0;

    while ([versionOneComp count] > pos || [versionTwoComp count] > pos) {
        NSInteger v1 = [versionOneComp count] > pos ? [[versionOneComp objectAtIndex:pos] integerValue] : 0;
        NSInteger v2 = [versionTwoComp count] > pos ? [[versionTwoComp objectAtIndex:pos] integerValue] : 0;
        if (v1 < v2) {
            return NSOrderedAscending;
        }
        else if (v1 > v2) {
            return NSOrderedDescending;
        }
        pos++;
    }

    return NSOrderedSame;
}

13voto

DonnaLea Points 2811

C'est une extension à Nathan de Vries réponse à résoudre le problème de l'1 < 1.0 < 1.0.0 etc.

Tout d'abord, nous pouvons aborder le problème de l'extra ".0"'s sur notre chaîne de version avec un NSString catégorie:

@implementation NSString (VersionNumbers)
- (NSString *)shortenedVersionNumberString {
    static NSString *const unnecessaryVersionSuffix = @".0";
    NSString *shortenedVersionNumber = self;

    while ([shortenedVersionNumber hasSuffix:unnecessaryVersionSuffix]) {
        shortenedVersionNumber = [shortenedVersionNumber substringToIndex:shortenedVersionNumber.length - unnecessaryVersionSuffix.length];
    }

    return shortenedVersionNumber;
}
@end

Ci-dessus, NSString catégorie, nous pouvons réduire nos numéros de version à la chute de l'inutile .0 s

NSString* requiredVersion = @"1.2.0";
NSString* actualVersion = @"1.1.5";

requiredVersion = [requiredVersion shortenedVersionNumberString]; // now 1.2
actualVersion = [actualVersion shortenedVersionNumberString]; // still 1.1.5

Maintenant, nous pouvons toujours utiliser le magnifiquement simple approche proposée par Nathan de Vries:

if ([requiredVersion compare:actualVersion options:NSNumericSearch] == NSOrderedDescending) {
  // actualVersion is lower than the requiredVersion
}

8voto

uliwitness Points 2085

Sparkle (un cadre pour MacOS) a un SUVersionComparator classe qui fait cela.

3voto

bladnman Points 1021

Je pensais que je venais de partager une fonction que j'ai rassemblé pour cette. Il n'est pas parfait du tout. Veuillez prendre un coup d'oeil que les exemples et les résultats. Mais si vous êtes de vérifier vos propres numéros de version (que j'ai à faire pour gérer des choses comme les migrations de base de données), puis cela peut aider un peu.

(aussi, supprimer le journal des déclarations dans la méthode, bien sûr. ceux qui sont là pour vous aider à voir ce qu'il fait c'est tout)

Tests:

[self isVersion:@"1.0" higherThan:@"0.1"];
[self isVersion:@"1.0" higherThan:@"0.9.5"];
[self isVersion:@"1.0" higherThan:@"0.9.5.1"];
[self isVersion:@"1.0.1" higherThan:@"1.0"];
[self isVersion:@"1.0.0" higherThan:@"1.0.1"];
[self isVersion:@"1.0.0" higherThan:@"1.0.0"];

// alpha tests
[self isVersion:@"1.0b" higherThan:@"1.0a"];
[self isVersion:@"1.0a" higherThan:@"1.0b"];
[self isVersion:@"1.0a" higherThan:@"1.0a"];
[self isVersion:@"1.0" higherThan:@"1.0RC1"];
[self isVersion:@"1.0.1" higherThan:@"1.0RC1"];

Résultats:

1.0 > 0.1
1.0 > 0.9.5
1.0 > 0.9.5.1
1.0.1 > 1.0
1.0.0 < 1.0.1
1.0.0 == 1.0.0
1.0b > 1.0a
1.0a < 1.0b
1.0a == 1.0a
1.0 < 1.0RC1       <-- FAILURE
1.0.1 < 1.0RC1     <-- FAILURE

notez que alpha travaille, mais vous devez être très prudent avec elle. une fois que vous aller de l'alpha à un certain point, vous ne pouvez pas étendre qu'en changeant tous les autres numéros mineurs derrière elle.

Code:

- (BOOL) isVersion:(NSString *)thisVersionString higherThan:(NSString *)thatVersionString {

// LOWER
if ([thisVersionString compare:thatVersionString options:NSNumericSearch] == NSOrderedAscending) {
    NSLog(@"%@ < %@", thisVersionString, thatVersionString);
    return NO;
}

// EQUAL
if ([thisVersionString compare:thatVersionString options:NSNumericSearch] == NSOrderedSame) {
    NSLog(@"%@ == %@", thisVersionString, thatVersionString);
    return NO;
}

NSLog(@"%@ > %@", thisVersionString, thatVersionString);
// HIGHER
return YES;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X