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.