Version vs build dans Xcode

660

J'ai une application que j'ai développée avec Xcode 3 et que j'ai récemment commencé à éditer avec Xcode 4. Dans le résumé de la cible, j'ai le formulaire cible de l'application iOS avec les champs: identifiant, version, build, appareils et cible de déploiement. Le champ de version est vide et le champ de construction est 3.4.0 (qui correspond à la version de l'application de quand j'étais encore en train de modifier avec Xcode 3).

Mes questions sont:

  1. Quelle est la différence entre les champs version et build?

  2. Pourquoi le champ de version était-il vide après la mise à niveau vers Xcode 4?

chris
la source
D'une part, je pense que c'est le numéro de build qui apparaît dans la liste des archives de Xcode Organizer. A part ça, je ne sais pas à quoi ça sert.
Daniel Dickison

Réponses:

1224

Apple a en quelque sorte réorganisé / réorienté les champs.

À l'avenir, si vous regardez sur l'onglet Info pour votre cible d'application, vous devez utiliser la "chaîne de versions Bundle, courte" comme version (par exemple, 3.4.0) et "version Bundle" comme version (par exemple, 500 ou 1A500 ). Si vous ne les voyez pas tous les deux, vous pouvez les ajouter. Celles-ci seront mappées aux zones de texte Version et Build appropriées dans l'onglet Résumé; ce sont les mêmes valeurs.

Lorsque vous affichez l'onglet Info, si vous cliquez avec le bouton droit et sélectionnez Afficher les clés / valeurs brutes , vous verrez que les noms réels sont CFBundleShortVersionString(Version) et CFBundleVersion(Build).

La version est généralement utilisée de la manière dont vous semblez l'avoir utilisée avec Xcode 3. Je ne sais pas à quel niveau vous demandez la différence Version / Build, donc je vais y répondre philosophiquement.

Il existe toutes sortes de schémas, mais le plus populaire est le suivant:

{MajorVersion}. {MinorVersion}. {Révision}

  • Version majeure - Changements majeurs, remaniements et changements de fonctionnalités
  • Version mineure - Améliorations mineures, ajouts aux fonctionnalités
  • Révision - Un numéro de patch pour les corrections de bugs

La version est ensuite utilisée séparément pour indiquer le nombre total de versions pour une version ou pour toute la durée de vie du produit.

De nombreux développeurs commencent le numéro de build à 0, et chaque fois qu'ils construisent, ils augmentent le nombre d'un, augmentant pour toujours. Dans mes projets, j'ai un script qui augmente automatiquement le nombre de build chaque fois que je construis. Voir les instructions ci-dessous.

  • La version 1.0.0 pourrait être la version 542. Il a fallu 542 versions pour arriver à une version 1.0.0.
  • La version 1.0.1 pourrait être la version 578.
  • La version 1.1.0 pourrait être la version 694.
  • La version 2.0.0 pourrait être la version 949.

D'autres développeurs, dont Apple, ont un numéro de build composé d'une version majeure + version mineure + nombre de builds pour la version. Ce sont les numéros de version du logiciel réels, par opposition aux valeurs utilisées pour le marketing.

Si vous allez dans le menu Xcode > À propos de Xcode , vous verrez les numéros de version et de build. Si vous appuyez sur le bouton Plus d'infos ... vous verrez un tas de versions différentes. Depuis le Plus d' info ... bouton a été enlevé dans Xcode 5, cette information est également disponible à partir du logiciel> Developer section du Système d' information sur l' application, disponible en ouvrant d' Apple Menu> À propos de ce Mac > System Report ... .

Par exemple, Xcode 4.2 (4C139). La version marketing 4.2 est la version 4 de la build majeure, la version mineure C de la build et le numéro de build 139. La prochaine version (probablement 4.3) sera probablement la version 4D de la build, et le numéro de build recommencera à 0 et augmentera à partir de là.

Les numéros de version / build de l'iPhone Simulator sont identiques, tout comme les iPhones, les Mac, etc.

  • 3.2: (7W367a)
  • 4,0: (8A400)
  • 4.1: (8B117)
  • 4.2: (8C134)
  • 4.3: (8H7)

Mise à jour : sur demande, voici les étapes pour créer un script qui s'exécute chaque fois que vous créez votre application dans Xcode pour lire le numéro de build, l'incrémenter et le réécrire dans le {App}-Info.plistfichier de l'application . Il y a des étapes supplémentaires facultatives si vous souhaitez écrire vos numéros de version / build dans vos Settings.bundle/Root*.plistfichiers.

Ceci est étendu de l'article pratique ici .

Dans Xcode 4.2 - 5.0:

  1. Chargez votre projet Xcode.
  2. Dans le volet gauche, cliquez sur votre projet tout en haut de la hiérarchie. Cela chargera l'éditeur de paramètres du projet.
  3. Sur le côté gauche du volet de la fenêtre centrale, cliquez sur votre application sous l'en- tête CIBLES . Vous devrez configurer cette configuration pour chaque cible de projet.
  4. Sélectionnez l' onglet Build Phases .
    • Dans Xcode 4, en bas à droite, cliquez sur le bouton Ajouter une phase de construction et sélectionnez Ajouter un script d'exécution .
    • Dans Xcode 5, sélectionnez le menu Éditeur > Ajouter une phase de construction > Ajouter une phase de construction de script d'exécution .
  5. Faites glisser et déposez la nouvelle phase Exécuter le script pour la déplacer juste avant la phase Copier les ressources du bundle (lorsque le fichier app-info.plist sera fourni avec votre application).
  6. Dans la nouvelle Exécuter le script de phase, définissez Shell : /bin/bash.
  7. Copiez et collez ce qui suit dans la zone de script pour les numéros de build entiers:

    buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
    buildNumber=$(($buildNumber + 1))
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"

    Comme l'a souligné @Bdebeez, l' outil de version générique d'Apple ( agvtool) est également disponible. Si vous préférez l'utiliser à la place, il y a quelques choses à changer en premier:

    • Sélectionnez l' onglet Paramètres de construction .
    • Dans la section Versioning , définissez la version actuelle du projet sur le numéro de build initial que vous souhaitez utiliser, par exemple, 1 .
    • De retour sur l' onglet Build Phases , faites glisser et déposez votre phase Run Script après la phase Copy Bundle Resources pour éviter une condition de concurrence critique lorsque vous essayez à la fois de créer et de mettre à jour le fichier source qui inclut votre numéro de build.

    Notez qu'avec la agvtoolméthode, vous pouvez toujours obtenir périodiquement des builds échoués / annulés sans erreurs. Pour cette raison, je ne recommande pas d'utiliser agvtoolce script.

    Néanmoins, dans votre phase d' exécution de script , vous pouvez utiliser le script suivant:

    "${DEVELOPER_BIN_DIR}/agvtool" next-version -all

    L' next-versionargument incrémente le numéro de build ( bumpest également un alias pour la même chose) et est mis à -alljour Info.plistavec le nouveau numéro de build.

  8. Et si vous disposez d'un ensemble de paramètres dans lequel vous affichez la version et la build, vous pouvez ajouter ce qui suit à la fin du script pour mettre à jour la version et la build. Remarque: modifiez les PreferenceSpecifiersvaleurs pour qu'elles correspondent à vos paramètres. PreferenceSpecifiers:2signifie regarder l'élément à l'index 2 sous le PreferenceSpecifierstableau dans votre fichier plist, donc pour un index basé sur 0, c'est le 3ème paramètre de préférence dans le tableau.

    productVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$INFOPLIST_FILE")
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:2:DefaultValue $buildNumber" Settings.bundle/Root.plist
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $productVersion" Settings.bundle/Root.plist

    Si vous utilisez agvtoolau lieu de lire Info.plistdirectement, vous pouvez ajouter ce qui suit à votre script à la place:

    buildNumber=$("${DEVELOPER_BIN_DIR}/agvtool" what-version -terse)
    productVersion=$("${DEVELOPER_BIN_DIR}/agvtool" what-marketing-version -terse1)
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:2:DefaultValue $buildNumber" Settings.bundle/Root.plist
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $productVersion" Settings.bundle/Root.plist
  9. Et si vous avez une application universelle pour iPad et iPhone, vous pouvez également définir les paramètres du fichier iPhone:

    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:2:DefaultValue $buildNumber" Settings.bundle/Root~iphone.plist    
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $productVersion" Settings.bundle/Root~iphone.plist
nekno
la source
17
"Dans mes projets, j'ai un script qui augmente automatiquement le nombre de build chaque fois que je le construis" - pouvez-vous partager comment faire? merci pour les détails des réponses et pour la question d'origine.
Zsolt
2
@Andrews - J'ai mis à jour ma réponse avec les détails du script de construction.
nekno
9
Pour incrémenter en nombres hexadécimaux, vous pouvez utiliserbuildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE") dec=$((0x$buildNumber)) buildNumber=$(($dec + 1)) hex=$(printf "%X" $buildNumber) /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $hex" "$INFOPLIST_FILE"
Alon Amir
8
En bref: HEX n'est pas autorisé dans l'AppStore.
Nicolas Miari
3
(Utilisateurs Xcode 5) Vous devrez peut-être modifier l'étape 5 pour lire: "Dans la barre de menus, sélectionnez Éditeur -> Ajouter une phase de
génération
72

(Je laisse juste ceci ici pour ma propre référence.) Cela montrera la version et la construction pour les champs "version" et "build" que vous voyez dans une cible Xcode:

- (NSString*) version {
    NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
    return [NSString stringWithFormat:@"%@ build %@", version, build];
}

Dans Swift

func version() -> String {
    let dictionary = NSBundle.mainBundle().infoDictionary!
    let version = dictionary["CFBundleShortVersionString"] as? String
    let build = dictionary["CFBundleVersion"] as? String
    return "\(version) build \(build)"
}
Dan Rosenstark
la source
2
OT: Vous avez une fuite dans votre méthode - vous alloc/ initla chaîne, qui conserve la chaîne, mais vous ne la libérez pas. Sur un objet que vous revenez d'une méthode, vous devez généralement utiliser une méthode pratique pour que la chaîne soit automatiquement libérée automatiquement, ou appelez autorelease. Soit: return [NSString stringWithFormat:@"%@ build %@", version, build]; OU return [[[NSString alloc] initWithFormat:@"%@ build %@", version, build] autorelease];
nekno
1
Merci @nekno, la réponse a changé, elle est donc compatible ARC ou non ARC.
Dan Rosenstark
2
Il est probablement préférable d'utiliser les constantes lorsqu'elles sont disponibles (par exemple kCFBundleVersionKey), pour éviter les fautes de frappe. Cependant, je n'ai pas pu en trouver un pour "CFBundleShortVersionString" :)
DannyA
Vous avez un bug dans le code rapide - vous appelez CFBundleShortVersionString deux fois
Yariv Nissim
Merci @ yar1vn, je l'ai corrigé et NON ce n'est pas à l'envers.
Dan Rosenstark
53

Le numéro de build est un numéro interne qui indique l'état actuel de l'application. Il diffère du numéro de version en ce qu'il n'est généralement pas accessible aux utilisateurs et ne dénote aucune différence / fonctionnalités / mises à niveau comme le ferait généralement un numéro de version.

Pensez-y comme ceci:

  • Build ( CFBundleVersion): le numéro de la construction. Habituellement, vous commencez à 1 et augmentez de 1 à chaque génération de l'application. Il permet rapidement des comparaisons dont la construction est plus récente et indique le sens de la progression de la base de code. Ceux-ci peuvent être extrêmement précieux lorsque vous travaillez avec QA et que vous devez vous assurer que les bogues sont enregistrés par rapport aux builds appropriés.
  • Version marketing ( CFBundleShortVersionString): numéro accessible à l'utilisateur que vous utilisez pour désigner cette version de votre application. Habituellement, cela suit un schéma de version Major.minor (par exemple MyAwesomeApp 1.2) pour permettre aux utilisateurs de savoir quelles versions sont des mises à jour de maintenance plus petites et quelles sont les nouvelles fonctionnalités.

Pour utiliser cela efficacement dans vos projets, Apple fournit un excellent outil appelé agvtool. Je recommande fortement d'utiliser cela car il est BEAUCOUP plus simple que de créer des scripts pour les changements de plist. Il vous permet de définir facilement le numéro de build et la version marketing. Il est particulièrement utile lors de l'écriture de scripts (par exemple, en mettant facilement à jour le numéro de build sur chaque build ou même en demandant quel est le numéro de build actuel). Il peut même faire des choses plus exotiques comme marquer votre SVN lorsque vous mettez à jour le numéro de build.

Pour l'utiliser:

  • Réglez votre projet dans Xcode, sous Versioning, pour utiliser "Apple Generic".
  • Dans le terminal
    • agvtool new-version 1 (définissez le numéro de build sur 1)
    • agvtool new-marketing-version 1.0 (définissez la version Marketing sur 1.0)

Voir la page de manuel de agvtoolpour une tonne de bonnes informations

Bdebeez
la source
un autre article sur agvtool Easy iPhone Application Versioning avec agvtool
Gon
25

Le script pour incrémenter automatiquement le numéro de build dans la réponse ci-dessus n'a pas fonctionné pour moi si le numéro de build est une valeur à virgule flottante, alors je l'ai légèrement modifié:

#!/bin/bash    
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=`echo $buildNumber +1|bc`
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
ale84
la source
21

Le numéro de version marketing est pour les clients, appelé numéro de version . Il commence avec 1.0 et remonte pour les mises à jour majeures vers 2.0 , 3.0 , pour les mises à jour mineures pour 1.1 , 1.2 et pour les corrections de bogues vers 1.0.1 , 1.0.2 . Ce nombre est orienté vers les versions et les nouvelles fonctionnalités.

Le numéro de build est principalement le nombre interne de builds qui ont été faites jusque-là. Mais certains utilisent d'autres numéros comme le numéro de branche du référentiel. Ce nombre doit être unique pour distinguer les différentes versions presque identiques.

Comme vous pouvez le voir, le numéro de build n'est pas nécessaire et c'est à vous de choisir le numéro de build que vous souhaitez utiliser. Donc, si vous mettez Xcodeà jour votre version principale, le champ de construction est vide. Le champ de version n'est peut-être pas vide !.


Pour obtenir le numéro de build en tant que NSStringvariable:

NSString * appBuildString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];

Pour obtenir le numéro de version sous forme de NSStringvariable:

NSString * appVersionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];

Si vous voulez les deux en un NSString:

NSString * versionBuildString = [NSString stringWithFormat:@"Version: %@ (%@)", appVersionString, appBuildString];

Ceci est testé avec Xcode version 4.6.3 (4H1503) . Le numéro de build est souvent écrit entre parenthèses / accolades. Le numéro de build est en hexadécimal ou décimal.

buildandversion


Dans Xcode, vous pouvez incrémenter automatiquement le numéro de build sous la forme d'un nombre décimal en plaçant ce qui suit dans la Run scriptphase de build dans les paramètres du projet

#!/bin/bash    
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"

Pour le numéro de build hexadécimal, utilisez ce script

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$((0x$buildNumber)) 
buildNumber=$(($buildNumber + 1)) 
buildNumber=$(printf "%X" $buildNumber)
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"

project_settings

Binarian
la source
6

Merci à @nekno et @ ale84 pour les bonnes réponses.

Cependant, j'ai modifié peu le script de @ ale84 pour incrémenter les numéros de build pour la virgule flottante.

la valeur de incl peut être modifiée en fonction de vos exigences de format flottant. Par exemple: si incl = .01, le format de sortie serait ... 1.19, 1.20, 1.21 ...

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
incl=.01
buildNumber=`echo $buildNumber + $incl|bc`
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
iHS
la source
1

Une autre façon consiste à définir le numéro de version dans appDelegate didFinishLaunchingWithOptions:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
     NSString * ver = [self myVersion];
     NSLog(@"version: %@",ver);

     NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
     [userDefaults setObject:ver forKey:@"version"];
     return YES;
}

- (NSString *) myVersion {
    NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
    return [NSString stringWithFormat:@"%@ build %@", version, build];
}
marque VanderWiele
la source