Ottenere informazioni sulla versione e sulla build con Swift


92

Sto tentando di accedere a Main NSBundle per recuperare le informazioni sulla versione e sulla build. Il fatto è che voglio provarlo in Swift, so come recuperarlo in Objective-C con Build.text = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];. Eppure non so da dove cominciare con swift, ho tentato di scriverlo nella nuova sintassi senza alcun risultato.


2
Mostra i tentativi che hai già fatto. È molto simile all'implementazione di Objective-C.
Mick MacCallum

Gennaio 2017 swift 2.3: let sVer = NSBundle.mainBundle (). InfoDictionary? ["CFBundleShortVersionString"] as? String let sBuild = NSBundle.mainBundle (). InfoDictionary? ["CFBundleVersion"] come? String self.myVersionLabel.text = String (format: "Version% @ Build% @", sVer !, sBuild!)
Matthew Ferguson

Risposte:


167

Cosa c'era di sbagliato nella sintassi di Swift? Questo sembra funzionare:

if let text = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
    print(text)
}

2
Perché questo è stato downvoted? Immagino che potrebbe essere più naturale, letma per il resto sembra corretto.
Tommy

Ah, ho dimenticato "as String" in modo che la variabile lo accetti come stringa. Grazie.
Ken-UbiDex

2
Questo sembra essere rotto con XCode 6 beta 3
Frédéric Adda

2
Questo ha funzionato per me in Xcode 6 beta 5:let text = NSBundle.mainBundle().infoDictionary["CFBundleVersion"]! as String
E. Barnes

@Dean Sembra che abbiano cambiato infoDictionary per restituire un optional. Ho modificato la risposta
Connor

118

Versione Swift 3/4

func version() -> String {
    let dictionary = Bundle.main.infoDictionary!
    let version = dictionary["CFBundleShortVersionString"] as! String
    let build = dictionary["CFBundleVersion"] as! String
    return "\(version) build \(build)"
} 

Versione Swift 2.x

func version() -> String {
    let dictionary = NSBundle.mainBundle().infoDictionary!
    let version = dictionary["CFBundleShortVersionString"] as String
    let build = dictionary["CFBundleVersion"] as String
    return "\(version) build \(build)"
}

come visto qui .


1
Ottieni la stessa chiave due volte, dovresti usare "CFBundleVersion" per la versione. Credo che sia una copia / errore di battitura passato :)
foog

Grazie @foOg è stato un errore di battitura. In effetti è al contrario: quella corta è la versione, quella normale è la build. Strano, lo so.
Dan Rosenstark

Versione Swift 3. se let infoPath = Bundle.main.path (forResource: "Info.plist", ofType: nil), let infoAttr = try? FileManager.default.attributesOfItem (atPath: infoPath), lascia infoDate = infoAttr [.creationDate] come? Data {return infoDate} data di ritorno ()
Ryan X

18

Per la versione finale di Xcode 6 utilizzare

NSBundle.mainBundle().infoDictionary?["CFBundleVersion"] as? String

Il "?" carattere dopo infoDictionary è importante qui


1
Dannazione. Di sicuro adoro tutto questo "optional ?, scartare!" sistema, è cristallino e così facile da leggere!
Jeroen Bouma

14

Ecco un modo semplice per ottenere Build e versione.

Per Swift 4.X

 if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
     print(version)
   }

 if let build = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
     print(build)
   }

Per l'obiettivo C

NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];

NSString * currentVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];

Fammi sapere se ci sono problemi. Questo sta funzionando per me.


13

Modo rapido per AppName, AppVersione BuildNumber...

if let dict = NSBundle.mainBundle().infoDictionary {
   if let version = dict["CFBundleShortVersionString"] as? String,
       let bundleVersion = dict["CFBundleVersion"] as? String,
       let appName = dict["CFBundleName"] as? String {
           return "You're using \(appName) v\(version) (Build \(bundleVersion))."
   }
}

Perché dovresti scartare i valori? Per quanto ne so, è impossibile che nessuno di questi valori sia nullo
Michael,

@Michael alcune persone scartano SEMPRE i valori opzionali. Alcune persone dicono che hai ragione.
Dan Rosenstark

2
Bundle.mainaveva un vuoto infoDictionaryper me; forse perché lo sto facendo all'interno di un framework, non di un eseguibile o di un'app? Bundle(for: MyClass.self)contiene i valori attesi.
Raphael

7

In rapido, lo farei come estensione per UIApplication, in questo modo:

extension UIApplication {

    func applicationVersion() -> String {

        return NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") as! String
    }

    func applicationBuild() -> String {

        return NSBundle.mainBundle().objectForInfoDictionaryKey(kCFBundleVersionKey as String) as! String
    }

    func versionBuild() -> String {

        let version = self.applicationVersion()
        let build = self.applicationBuild()

        return "v\(version)(\(build))"
    }
}

Quindi puoi semplicemente usare quanto segue per ottenere tutto ciò di cui hai bisogno:

let version = UIApplication.sharedApplication.applicationVersion() // 1
let build = UIApplication.sharedApplication.applicationBuild() // 80
let both = UIApplication.sharedApplication.versionBuild() // 1(80)

7

// Restituisce il numero di versione dell'app

public static var appVersion: String? {
    return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String
}

// Restituisce il numero di build dell'app

public static var appBuild: String? {
    return Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String
}

6

Swift 5.0

Ho creato un wrapper per Swift 5 per ottenere alcune stringhe relative alle app in un unico punto in tutte le mie app, chiamato AppInfo .

struct AppInfo {

var appName : String {
    return readFromInfoPlist(withKey: "CFBundleName") ?? "(unknown app name)"
}

var version : String {
    return readFromInfoPlist(withKey: "CFBundleShortVersionString") ?? "(unknown app version)"
}

var build : String {
    return readFromInfoPlist(withKey: "CFBundleVersion") ?? "(unknown build number)"
}

var minimumOSVersion : String {
    return readFromInfoPlist(withKey: "MinimumOSVersion") ?? "(unknown minimum OSVersion)"
}

var copyrightNotice : String {
    return readFromInfoPlist(withKey: "NSHumanReadableCopyright") ?? "(unknown copyright notice)"
}

var bundleIdentifier : String {
    return readFromInfoPlist(withKey: "CFBundleIdentifier") ?? "(unknown bundle identifier)"
}

var developer : String { return "my awesome name" }

// lets hold a reference to the Info.plist of the app as Dictionary
private let infoPlistDictionary = Bundle.main.infoDictionary

/// Retrieves and returns associated values (of Type String) from info.Plist of the app.
private func readFromInfoPlist(withKey key: String) -> String? {
    return infoPlistDictionary?[key] as? String
     }
}

Puoi usarlo in questo modo:

print("The apps name = \(AppInfo.appname)")

Quando in Swift un valore non è disponibile viene utilizzato nil. IMO dovresti restituire zero invece di stringhe segnaposto personalizzate.
Luca Angeletti il

Ecco perché è un involucro: per ottenere sempre qualcosa in cambio. La situazione zero non è realmente "distrutta", è ancora lì, ma già gestita. Altrimenti dovresti gestire la situazione "nulla" in un altro punto della tua app.
LukeSideWalker,

grazie amico. inoltre, l'ultima parentesi graffa è fuori dal blocco di codice. :)
Mark Perkins

2
il nome dell'app può anche essereCFBundleDisplayName
gondo

2

Questo codice funziona per Swift 3, Xcode 8:

let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") ?? "0"
let build = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") ?? "0"

2

Per Swift 3, Sostituisci NSBundle con Bundle e mainBundle viene sostituito semplicemente da main.

let AppVersion = Bundle.main.infoDictionary!["CFBundleVersion"] as! String

1

[Aggiornamento: Xcode 6.3.1] Ho provato tutto quanto sopra e nessuno di questi funziona in Xcode 6.3.1 ma ho scoperto che questo fa:

(NSBundle.mainBundle().infoDictionary?["CFBundleVersion"] as? String)!

1

Un'altra opzione è definire in AppDelegate le variabili:

var applicationVersion:String {
    return NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") as! String
}
var applicationBuild:String  {
    return NSBundle.mainBundle().objectForInfoDictionaryKey(kCFBundleVersionKey as String) as! String
}
var versionBuild:String  {
    let version = self.applicationVersion
    let build = self.applicationBuild
    return "version:\(version) build:(\(build))"
}

a cui è possibile fare riferimento come variabili in AppDelegate


0

Swift 3:

let textVersion
 = Bundle.main.infoDictionary?["CFBundleVersion"] as? String

0

Versione SWIFT 3

if let infoPath = Bundle.main.path(forResource: "Info.plist", ofType: nil),
        let infoAttr = try? FileManager.default.attributesOfItem(atPath: infoPath),
        let infoDate = infoAttr[.creationDate] as? Date
{
    return infoDate
}
return Date()

0

Per avere risultati per framework puoi usare

let version = Bundle(for: type(of: self)).infoDictionary?["CFBundleShortVersionString"] as? String

o nei test

let version = Bundle(for: <SomeClass>.self).infoDictionary?["CFBundleShortVersionString"] as? String
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.