Comment afficher par programme la version / le numéro de build de la cible dans l'application iOS?

135

Comment puis-je obtenir par programme la valeur de target version, comme dans l'image ci-dessous?

Comme vu dans la fenêtre Propriétés de la cible de mon projet Xcode. Je veux l'afficher dans l'écran de démarrage de mon application afin de savoir quelle version les gens utilisent actuellement?

svelte
la source

Réponses:

392

Il y a 2 numéros!

Le numéro de version marketing est pour les clients, appelé numéro de version . Il commence par 1.0 et monte pour les mises à jour majeures vers 2.0 , 3.0 , pour les mises à jour mineures vers 1.1 , 1.2 et pour les corrections de bogues vers 1.0.1 , 1.0.2 . Ce numéro est orienté sur les versions et les nouvelles fonctionnalités. Il ne doit pas s'arrêter à 9, 1.11.23 est un numéro de version raisonnable.

Le numéro de build est principalement le nombre interne de builds qui ont été réalisés jusque-là. Mais certains utilisent d'autres nombres comme le numéro de branche du référentiel ou son numéro de validation. Ce numéro doit être unique pour distinguer les différentes versions, qui n'ont que des modifications incrémentielles mineures.


Pour obtenir le numéro de version :

Objectif c:

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

Swift <3.0:

let appVersionString: String = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") as! String

Swift 3.0+ (testé avec 5.0):

let appVersionString: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String

Pour obtenir le numéro de build :

Objectif c:

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

Swift <3.0:

let buildNumber: String = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleVersion") as! String

Swift 3.0+ (testé jusqu'à 5.0):

let buildNumber: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String   

Si vous voulez les deux en un:

Utilisez d'abord les lignes ci-dessus, puis la suivante.

Objectif c:

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

Swift (testé jusqu'à 5.0):

let versionAndBuildNumber: String = "\(appVersionString) (\(buildNumber))"

Remarques:

Les valeurs du bundle principal ne sont pas toujours présentes, par exemple dans une application de ligne de commande, il n'y a pas de CFBundleShortVersionStringou CFBundleVersion, donc les méthodes retourneront nilet cela plantera car dans le code, cela fait un downcast incorrect. Mais dans les applications Cocoa iOS et Mac normales, ces valeurs sont définies et ne seront pas supprimées.

Ceci est testé avec Xcode version 7.3 (7D175) . 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 version sous forme de nombre décimal en plaçant ce qui suit dans la Run scriptphase de construction 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 version 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"

Pour Xcodefaire ce qui suit:

Étape 1

étape 1

Étape 2

étape 2

Étape 3

étape 3

Binaire
la source
4
Juste pour ajouter l'exemple ci-dessus, "CFBundleVersion" est le Build = 300, "CFBundleShortVersionString" est la Version = 0.41. La réponse de Viktor devrait être la bonne réponse.
justinkoh
1
J'ai eu des problèmes avec les nombres hexadécimaux une fois. Apple déclare utiliser des entiers: developer.apple.com/library/ios/documentation/general/Reference/…
hashier
Savez-vous s'il existe des constantes de chaîne pour @ "CFBundleShortVersionString" et @ "CFBundleVersion"?
igrek
Maintenant que les systèmes CI / CD sont assez courants, vous voudrez peut-être souligner les pièges liés à l'utilisation de scripts de construction pour définir les numéros de version avec ceux-ci.
Sam Ballantyne
1
Les choses ont été renommées pour Swift 3.0: c'est Bundle.main.object(forInfoDictionaryKey: "...")maintenant.
Raphael
13

Vous n'avez rien à changer dans votre projet ou Xcode. Voici la version Swift pour les deux séparément:

let versionNumber = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") as! String
let buildNumber = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleVersion") as! String

Il est inclus dans ce dépôt, vérifiez-le:

https://github.com/goktugyil/EZSwiftExtensions

Esqarrouth
la source
quelle réponse? je ne le vois pas
Esqarrouth
Il n'y a qu'une seule réponse, c'est dans son deuxième paragraphe
Daniel Galasko
3
Ouais, 1. Il y a trop de bruit et pas beaucoup de signal dans sa réponse. 2. C'est rapide, c'est objectif-c. 3. Thats from ios5 era
Esqarrouth
Les choses ont été renommées pour Swift 3.0: c'est Bundle.main.object(forInfoDictionaryKey: "...")maintenant.
Raphael
5

Voici le même code pour Swift 3 :

let versionNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
let buildNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String
tanaschita
la source
Bundle.mainavait un vide infoDictionarypour moi; peut-être parce que je le fais à partir d'un cadre, pas d'un exécutable ou d'une application? Bundle(for: MyClass.self)contient les valeurs attendues.
Raphael
4

Afficher la version et le numéro de build par programme - Swift 4.0

let versionNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") ?? "1.0"

let buildNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") ?? "1.0"            

let versionAndBuildNumber = "Ver #\(versionNumber) ( Build #\(buildNumber) )"
Sandip Patel - SM
la source
1

Vous pouvez également utiliser comme

var appVersion: String {
  //versionNumber
  let versionNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") ?? "1.0"

  //buildNumber
  let buildNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") ?? "1.0"

  return "Version: #\(versionNumber) (#\(buildNumber))"
}

Ensuite, vous pouvez utiliser n'importe où lorsque vous déclarez Globalement.

print(appVersion)

Production:

Version: #1.0 (#1.0.3)
Sivabalaa Jothibose
la source
1

J'ai fait une extension pour Bundle donc ce sera facile à utiliser

extension Bundle {
    var releaseVersionNumber: String? {
        return infoDictionary?["CFBundleShortVersionString"] as? String
    }

    var buildVersionNumber: String? {
        return infoDictionary?["CFBundleVersion"] as? String
    }

    var applicationName: String {
        return infoDictionary?["CFBundleDisplayName"] as? String ?? "ADKATech"
    }

    var applicationReleaseDate: String {
        return infoDictionary?["ApplicationReleaseDate"] as? String ?? Date().description
    }

    var applicationReleaseNumber: Int {
        return infoDictionary?["ApplicationReleaseNumber"] as? Int ?? 0
    }

    var releaseVersionNumberPretty: String {
        return "\(releaseVersionNumber ?? "1.0.0")"
    }

    var buildVersionNumberPretty: String {
        return "\(buildVersionNumber ?? "1")"
    }
}
Amr en colère
la source