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.