web-dev-qa-db-fra.com

Comment puis-je obtenir la version de l'application et le numéro de version à l'aide de Swift?

J'ai une application IOS avec un back-end Azure et je souhaite enregistrer certains événements, tels que les connexions et les versions des utilisateurs de l'application en cours d'exécution.

Comment puis-je retourner la version et le numéro de build à l'aide de Swift?

330
Øyvind Vik

EDIT

Mis à jour pour Swift 4.2

let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String

EDIT

Comme l'a souligné @azdev sur la nouvelle version de Xcode, vous obtiendrez une erreur de compilation en essayant ma solution précédente. Pour résoudre ce problème, il vous suffit de l'éditer comme suggéré pour déballer le dictionnaire de bundles à l'aide d'un!

let nsObject: AnyObject? = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"]

Fin d'édition

Utilisez simplement la même logique que dans Objective-C mais avec quelques changements mineurs

//First get the nsObject by defining as an optional anyObject
let nsObject: AnyObject? = NSBundle.mainBundle().infoDictionary["CFBundleShortVersionString"]

//Then just cast the object as a String, but be careful, you may want to double check for nil
let version = nsObject as String

J'espère que cela vous aide.

David

337
David

Je sais que cela a déjà été répondu, mais personnellement, je pense que c'est un peu plus propre:

Swift 3.0:

 if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
    self.labelVersion.text = version
}

Swift <2.

if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String {
    self.labelVersion.text = version
}

De cette façon, la version if let prend en charge le traitement conditionnel (en définissant le texte de l'étiquette dans mon cas) et si infoDictionary ou CFBundleShortVersionString sont nuls, le déroulement facultatif entraîne l'omission du code.

269
Timothy Tripp

Mise à jour pour Swift 3.

Les préfixes NS- ont maintenant disparu dans Swift 3.0 et plusieurs propriétés/méthodes ont changé de nom pour devenir plus Swifty. Voici à quoi cela ressemble maintenant:

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

Bundle.main.releaseVersionNumber
Bundle.main.buildVersionNumber

Ancienne réponse mise à jour

Je travaille beaucoup avec Frameworks depuis ma réponse initiale et je voulais donc mettre à jour ma solution pour une solution à la fois plus simple et beaucoup plus utile dans un environnement multi-bundle:

extension NSBundle {

    var releaseVersionNumber: String? {
        return self.infoDictionary?["CFBundleShortVersionString"] as? String
    }

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

}

Désormais, cette extension sera utile dans les applications pour identifier à la fois le paquet principal et tout autre paquet inclus (tel qu'un cadre partagé pour la programmation par extension ou des troisièmes cadres comme AFNetworking), comme ceci:

NSBundle.mainBundle().releaseVersionNumber
NSBundle.mainBundle().buildVersionNumber

// or...

NSBundle(URL: someURL)?.releaseVersionNumber
NSBundle(URL: someURL)?.buildVersionNumber

Réponse originale

Je voulais améliorer certaines des réponses déjà postées. J'ai écrit une extension de classe qui peut être ajoutée à votre chaîne d'outils pour gérer cela de manière plus logique.

extension NSBundle {

class var applicationVersionNumber: String {
    if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"]

comme? String {return version} return "Numéro de version non disponible"}

class var applicationBuildNumber: String {
    if let build = NSBundle.mainBundle().infoDictionary?["CFBundleVersion"] as? String {
        return build
    }
    return "Build Number Not Available"
}

}

Alors maintenant, vous pouvez y accéder facilement en:

let versionNumber = NSBundle.applicationVersionNumber
230
Blake Merryman

Je sais aussi que cela a déjà été répondu, mais j'ai résumé les réponses précédentes:

(*) Mis à jour pour les extensions

extension Bundle {
    var releaseVersionNumber: String? {
        return infoDictionary?["CFBundleShortVersionString"] as? String
    }
    var buildVersionNumber: String? {
        return infoDictionary?["CFBundleVersion"] as? String
    }
    var releaseVersionNumberPretty: String {
        return "v\(releaseVersionNumber ?? "1.0.0")"
    }
}

Usage:

someLabel.text = Bundle.main.releaseVersionNumberPretty

@Deprecated: réponses anciennes

Swift 3.1:

class func getVersion() -> String {
    guard let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else {
        return "no version info"
    }
    return version
}

Pour les anciennes versions:

class func getVersion() -> String {
    if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String {
        return version
    }
    return "no version info"
}

Donc, si vous voulez définir le texte de l'étiquette ou si vous voulez utiliser quelque part ailleurs;

self.labelVersion.text = getVersion()
65
Gunhan

Pour Swift 4.

let version = Bundle.main.infoDictionary!["CFBundleShortVersionString"]!
let build = Bundle.main.infoDictionary!["CFBundleVersion"]!
31
Iryna Batvina

J'ai fait une extension sur bundle

extension Bundle {

    var appName: String {
        return infoDictionary?["CFBundleName"] as! String
    }

    var bundleId: String {
        return bundleIdentifier!
    }

    var versionNumber: String {
        return infoDictionary?["CFBundleShortVersionString"] as! String 
    }

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

}

et ensuite l'utiliser

versionLabel.text = "\(Bundle.main.appName) v \(Bundle.main.versionNumber) (Build \(Bundle.main.buildNumber))"
27
carmen_munich

Pour Swift 3.0 NSBundle ne fonctionne pas, le code suivant fonctionne parfaitement.

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

et pour juste le numéro de build, c'est:

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

Confusion "CFBundleVersion" est le numéro build tel que saisi dans Xcode sous General-> Identity.

16
Tejas

Xcode 8, Swift 3:

let gAppVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") ?? "0"
let gAppBuild = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") ?? "0"
14
Crashalot

Xcode 9.4.1 Swift 4.1

Notez l'utilisation de localizedInfoDictionary pour choisir la version linguistique appropriée du nom d'affichage de l'ensemble.

var displayName: String?
var version: String?
var build: String?

override func viewDidLoad() {
    super.viewDidLoad()

    // Get display name, version and build

    if let displayName = Bundle.main.localizedInfoDictionary?["CFBundleDisplayName"] as? String {
        self.displayName = displayName
    }
    if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
        self.version = version
    }
    if let build = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
        self.build = build
    }
}
14
Hugo F

Swift 4, extension utile pour Bundle

import Foundation

public extension Bundle {

    public var shortVersion: String {
        if let result = infoDictionary?["CFBundleShortVersionString"] as? String {
            return result
        } else {
            assert(false)
            return ""
        }
    }

    public var buildVersion: String {
        if let result = infoDictionary?["CFBundleVersion"] as? String {
            return result
        } else {
            assert(false)
            return ""
        }
    }

    public var fullVersion: String {
        return "\(shortVersion)(\(buildVersion))"
    }
}
11
maslovsa

Ma réponse (en août 2015), étant donné Swift continue d'évoluer:

let version = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
9
Charlie Seligman

Bundle + Extensions.Swift

import Foundation

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

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

    var bundleName: String? {
        return infoDictionary?["CFBundleName"] as? String
    }
}

Usage:

someLabel.text = Bundle.main.versionNumber
8
Giang

Après avoir examiné la documentation, je pense que ce qui suit est plus propre:

let version = 
NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") 
as? String

Source : "L'utilisation de cette méthode est préférable à d'autres méthodes d'accès car elle renvoie la valeur localisée d'une clé lorsqu'elle est disponible."

6
Daniel Armyr

Pour Swift 1.2 c'est:

let version = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"] as! String
let build = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
5
Michael Samoylov

Swift 3:

Numéro de version

if let versionNumberString = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String { // do something }

Numéro de construction

if let buildNumberString = Bundle.main.infoDictionary?["CFBundleVersion"] as? String { // do something }
4
jasonnoahchoi

Swift 4

func getAppVersion() -> String {
    return "\(Bundle.main.infoDictionary!["CFBundleShortVersionString"] ?? "")"
}

Bundle.main.infoDictionary! ["CFBundleShortVersionString"]

ancienne syntaxe Swift

let appVer: AnyObject? = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"]
3
Harshil Kotecha
extension UIApplication {

    static var appVersion: String {
        if let appVersion = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") {
            return "\(appVersion)"
        } else {
            return ""
        }
    }

    static var build: String {
        if let buildVersion = NSBundle.mainBundle().objectForInfoDictionaryKey(kCFBundleVersionKey as String) {
            return "\(buildVersion)"
        } else {
            return ""
        }
    }

    static var versionBuild: String {
        let version = UIApplication.appVersion
        let build = UIApplication.build

        var versionAndBuild = "v\(version)"

        if version != build {
            versionAndBuild = "v\(version)(\(build))"
        }

        return versionAndBuild
    }

}

Attention: vous devez utiliser si laissé ici au cas où la version ou la construction de l'application n'est pas définie, ce qui entraînerait un crash si vous essayez de l'utiliser! à déballer.

2
futantan
public var appVersionNumberString: String {
get {
    return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
}
}
2
Mohammad Razipour

Voici une version mise à jour pour Swift 3.2:

extension UIApplication
{
    static var appVersion:String
    {
        if let appVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")
        {
            return "\(appVersion)"
        }
        return ""
    }

    static var buildNumber:String
    {
        if let buildNum = Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String)
        {
            return "\(buildNum)"
        }
        return ""
    }

    static var versionString:String
    {
        return "\(appVersion).\(buildNumber)"
    }
}
1
BadmintonCat

OP a demandé le numéro de version et le numéro de build. Malheureusement, la plupart des réponses ne fournissent pas ces deux options. En outre, d'autres ajoutent des méthodes d'extension inutiles. En voici un qui est assez simple et qui résout le problème de OP:

// Example output: "1.0 (234)"
private func versionAndBuildNumber() -> String {
  let versionNumber = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
  let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
  if let versionNumber = versionNumber, let buildNumber = buildNumber {
    return "\(versionNumber) (\(buildNumber))"
  } else if let versionNumber = versionNumber {
    return versionNumber
  } else if let buildNumber = buildNumber {
    return buildNumber
  } else {
    return ""
  }
}
1
Senseful

Swift 4

// Commencez par obtenir le nsObject en le définissant comme un AnyObject facultatif.

let nsObject: AnyObject? = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as AnyObject

// Puis transformez simplement l'objet en String, mais attention, vous pouvez vérifier que rien ne vaut

let version = nsObject as! String
1
Prabhat Kasera

pour les personnes intéressées, il existe une bibliothèque agréable et soignée appelée SwifterSwift disponible sur github et également entièrement documentée pour chaque version de Swift (voir swifterswift.com ).

en utilisant cette bibliothèque, lire la version de l'application et le numéro de build serait aussi simple que cela:

import SwifterSwift

let buildNumber = SwifterSwift.appBuild
let version = SwifterSwift.appVersion
1
MFA
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
        lblVersion.text = "Version \(version)"

    }
0
ishwar lal janwa

Mise à jour pour Swift 5

voici une fonction que j'utilise pour décider d'afficher ou non une page "l'application mise à jour". Il retourne le numéro de build que je convertis en Int:

if let version: String = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
        guard let intVersion = Int(version) else { return }

        if UserDefaults.standard.integer(forKey: "lastVersion") < intVersion {
            print("need to show popup")
        } else {
            print("Don't need to show popup")
        }

        UserDefaults.standard.set(intVersion, forKey: "lastVersion")
    }

Si jamais utilisé auparavant, il retournera 0 qui est inférieur au numéro de build actuel. Pour ne pas afficher cet écran aux nouveaux utilisateurs, ajoutez simplement le numéro de build après la première connexion ou à la fin de l'intégration.

0
Giovanni Palusa

Vous pouvez maintenant utiliser une constante pour cela, plutôt que de devoir utiliser du code très typé comme avant, ce qui rend les choses encore plus pratiques.

var appVersion: String {
    return Bundle.main.infoDictionary![kCFBundleVersionKey as String] as! String
}
0
TheNeil

Fonction utilitaire simple pour renvoyer la version de l'application sous la forme Int

func getAppVersion() -> Int {

        if let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {

            let appVersionClean = appVersion.replacingOccurrences(of: ".", with: "", options: NSString.CompareOptions.literal, range:nil)

            if let appVersionNum = Int(appVersionClean) {
                return appVersionNum
            }
        }
        return 0
    }
0
Tiago Mendes