Obtener información de versión y compilación con Swift


92

Estoy intentando obtener acceso al NSBundle principal para recuperar la información de versión y compilación. La cosa es que quiero probarlo rápidamente, sé cómo recuperarlo en Objective-C con Build.text = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];. Sin embargo, no sé por dónde empezar con swift, he intentado escribirlo en la nueva sintaxis sin éxito.


2
Muestra los intentos que ya has hecho. Es muy similar a la implementación de Objective-C.
Mick MacCallum

Enero de 2017 swift 2.3: deje sVer = NSBundle.mainBundle (). InfoDictionary? ["CFBundleShortVersionString"] como? String let sBuild = NSBundle.mainBundle (). InfoDictionary? ["CFBundleVersion"] como? String self.myVersionLabel.text = String (formato: "Versión% @ Build% @", sVer !, sBuild!)
Matthew Ferguson

Respuestas:


167

¿Qué pasaba con la sintaxis de Swift? Esto parece funcionar:

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

2
¿Por qué se votó en contra? Supongo que podría ser más natural, letpero por lo demás parece correcto.
Tommy

Ah, olvidé el "como cadena" para que la variable lo aceptara como una cadena. Gracias.
Ken-UbiDex

2
Eso parece estar roto con XCode 6 beta 3
Frédéric Adda

2
Esto funcionó para mí en Xcode 6 beta 5:let text = NSBundle.mainBundle().infoDictionary["CFBundleVersion"]! as String
E. Barnes

@Dean Parece que cambiaron infoDictionary para devolver un opcional. He editado la respuesta
Connor

118

Versión 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)"
} 

Versión 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)"
}

como se ve aquí .


1
Obtiene la misma clave dos veces, debe usar "CFBundleVersion" para la versión. Supongo que es una copia / error tipográfico anterior :)
foOg

Gracias @foOg fue un error tipográfico. De hecho, es al revés: la corta es la versión, la normal es la compilación. Extraño, lo sé.
Dan Rosenstark

Versión Swift 3. if let infoPath = Bundle.main.path (forResource: "Info.plist", ofType: nil), let infoAttr = try? FileManager.default.attributesOfItem (atPath: infoPath), deje infoDate = infoAttr [.creationDate] como? Fecha {return infoDate} Fecha de regreso ()
Ryan X

18

Para la versión final de Xcode 6 use

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

Los "?" carácter después del infoDiccionario es importante aquí


1
Maldición. Seguro que me encanta todo este "¿opcional? ¡Desenvolver!" sistema, es muy claro y muy fácil de leer.
Jeroen Bouma

14

Esta es una forma sencilla de obtener compilación y versión.

Para 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)
   }

Para el objetivo C

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

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

Avísame si hay algún problema. Esto es trabajo para mí.


13

Camino rápido para AppName, AppVersiony 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))."
   }
}

¿Por qué necesitarías desenvolver los valores? Que yo sepa, es imposible que ninguno de esos valores sea nulo
Michael

@Michael algunas personas SIEMPRE desenvuelven valores opcionales. Algunas personas dicen que tienes razón.
Dan Rosenstark

2
Bundle.maintenía un vacío infoDictionarypara mí; tal vez porque lo hago desde un marco, no un ejecutable o una aplicación? Bundle(for: MyClass.self)contiene los valores esperados.
Raphael

7

Rápidamente, lo convertiría en una extensión para UIApplication, así:

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))"
    }
}

Entonces puede usar lo siguiente para obtener todo lo que necesita:

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

7

// Devuelve el número de versión de la aplicación

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

// Devuelve el número de compilación de la aplicación

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

6

Swift 5.0

Creé un contenedor para Swift 5 para obtener algunas cadenas relacionadas con la aplicación en un solo lugar en todas mis aplicaciones, llamado 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
     }
}

Puedes usarlo así:

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

Cuando en Swift un valor no está disponible, se usa nil. En mi opinión, debe devolver nil en lugar de cadenas de marcador de posición personalizadas.
Luca Angeletti

Por eso es un envoltorio: para obtener siempre algo a cambio. La situación nula no está realmente "destruida", todavía está ahí, pero ya pre-manejada. De lo contrario, tendría que manejar la situación "nula" en otro lugar de su aplicación.
LukeSideWalker

gracias amigo. Además, la última llave está fuera del bloque de código. :)
Mark Perkins

2
El nombre de la aplicación también puede serCFBundleDisplayName
gondo

2

Este código funciona para Swift 3, Xcode 8:

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

2

Para Swift 3, reemplace NSBundle con Bundle y mainBundle se reemplaza simplemente por main.

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

1

[Actualización: Xcode 6.3.1] Probé todo lo anterior y ninguno de estos funciona en Xcode 6.3.1 pero descubrí que esto sí:

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

1

Otra opción es definir en el AppDelegate las variables:

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))"
}

que se pueden referenciar como variables en AppDelegate


0

Swift 3:

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

0

Versión 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

Para tener un resultado para el marco, puede usar

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

o en pruebas

let version = Bundle(for: <SomeClass>.self).infoDictionary?["CFBundleShortVersionString"] as? String
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.