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.