Version abrufen und Informationen mit Swift erstellen


89

Ich versuche, Zugriff auf das Haupt-NSBundle zu erhalten, um Versions- und Build-Informationen abzurufen. Die Sache ist, ich möchte es schnell versuchen, ich weiß, wie man es in Objective-C mit abruft Build.text = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];. Ich weiß jedoch nicht, wo ich mit Swift anfangen soll. Ich habe versucht, es ohne Erfolg in der neuen Syntax zu schreiben.


2
Zeigen Sie die Versuche an, die Sie bereits unternommen haben. Es ist der Objective-C-Implementierung sehr ähnlich.
Mick MacCallum

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

Antworten:


163

Was war falsch an der Swift-Syntax? Das scheint zu funktionieren:

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

2
Warum wurde das abgelehnt? Ich denke, es könnte natürlicher sein als, letaber es sieht ansonsten richtig aus.
Tommy

Ah, ich habe das "as String" vergessen, damit die Variable es als String akzeptiert. Danke dir.
Ken-UbiDex

2
Das scheint mit XCode 6 Beta 3
Frédéric Adda

2
Dies funktionierte für mich in Xcode 6 Beta 5:let text = NSBundle.mainBundle().infoDictionary["CFBundleVersion"]! as String
E. Barnes

@ Dean Es sieht so aus, als hätten sie infoDictionary geändert, um ein optionales zurückzugeben. Ich habe die Antwort bearbeitet
Connor

116

Schnelle 3/4 Version

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

Swift 2.x Version

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

wie hier gesehen .


1
Sie erhalten den gleichen Schlüssel zweimal, sollten "CFBundleVersion" für die Version verwenden. Ich denke, es ist eine Kopie / Tippfehler in der Vergangenheit :)
für den

Danke @foOg es war ein Tippfehler. Tatsächlich ist es rückwärts: Die kurze ist die Version, die reguläre ist der Build. Seltsam, ich weiß.
Dan Rosenstark

Swift 3 Version. Wenn let infoPath = Bundle.main.path (forResource: "Info.plist", ofType: nil), let infoAttr = try? FileManager.default.attributesOfItem (atPath: infoPath), lassen Sie infoDate = infoAttr [.creationDate] als? Datum {return infoDate} return Date ()
Ryan X

18

Für die endgültige Version von Xcode 6 verwenden

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

Das "?" Zeichen nach infoDictionary ist hier wichtig


1
Verdammt. Ich liebe dieses ganze "optional?, Auspacken!" System, es ist kristallklar und so einfach zu lesen!
Jeroen Bouma

14

Hier ist eine einfache Möglichkeit, Build und Version zu erhalten.

Für 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)
   }

Für Ziel C.

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

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

Lassen Sie mich wissen, wenn ein Problem vorliegt. Das funktioniert bei mir.


13

Swifty Weg AppName, AppVersionund 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))."
   }
}

Warum sollten Sie die Werte auspacken müssen? Meines Wissens ist es unmöglich, dass einer dieser Werte Null ist
Michael

@ Michael einige Leute packen IMMER optionale Werte aus. Einige Leute sagen, du hast recht.
Dan Rosenstark

2
Bundle.mainhatte eine leere infoDictionaryfür mich; Vielleicht, weil ich es innerhalb eines Frameworks mache, nicht einer ausführbaren Datei oder App? Bundle(for: MyClass.self)enthält die erwarteten Werte.
Raphael

7

In Kürze würde ich es als Erweiterung für UIApplication wie folgt machen:

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

Dann können Sie einfach Folgendes verwenden, um alles zu erhalten, was Sie benötigen:

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

7

// Gibt die Versionsnummer der App zurück

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

// Die Build-Nummer der App zurückgeben

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

5

Swift 5.0

Ich habe einen Wrapper für Swift 5 erstellt, um einige App-bezogene Zeichenfolgen an einer Stelle in allen meinen Apps mit dem Namen AppInfo abzurufen .

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

Sie können es so verwenden:

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

Wenn in Swift ein Wert nicht verfügbar ist, wird null verwendet. IMO sollten Sie null anstelle von benutzerdefinierten Platzhalterzeichenfolgen zurückgeben.
Luca Angeletti

Deshalb ist es ein Wrapper: Um immer etwas zurückzubekommen. Die Nullsituation ist nicht wirklich "zerstört", sie ist immer noch da, aber bereits vorbehandelt. Andernfalls müssten Sie die "Null" -Situation an einer anderen Stelle in Ihrer App behandeln.
LukeSideWalker

Danke, Alter. Außerdem befindet sich Ihre letzte geschweifte Klammer außerhalb des Codeblocks. :)
Mark Perkins

2
App-Name kann auch seinCFBundleDisplayName
Gondo

2

Dieser Code funktioniert für Swift 3, Xcode 8:

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

2

Bei Swift 3 wird NSBundle durch Bundle ersetzen, und mainBundle wird einfach durch main ersetzt.

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

1

[Update: Xcode 6.3.1] Ich habe alle oben genannten Funktionen ausprobiert und keine dieser Funktionen funktioniert in Xcode 6.3.1, aber ich habe festgestellt, dass dies Folgendes bewirkt:

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

1

Eine weitere Option besteht darin, im AppDelegate die Variablen zu definieren:

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

Dies kann im AppDelegate als Variable bezeichnet werden


0

Swift 3:

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

0

SWIFT 3 Version

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

Um ein Ergebnis für das Framework zu erhalten, können Sie es verwenden

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

oder in Tests

let version = Bundle(for: <SomeClass>.self).infoDictionary?["CFBundleShortVersionString"] as? String
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.