Pobieranie informacji o wersji i kompilacji za pomocą Swift


92

Próbuję uzyskać dostęp do głównego pakietu NSBundle w celu pobrania informacji o wersji i kompilacji. Chodzi o to, że chcę to szybko wypróbować, wiem, jak go odzyskać w Objective-C za pomocą Build.text = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];. Jednak nie wiem, od czego zacząć ze swiftem, bezskutecznie próbowałem napisać go w nowej składni.


2
Pokaż podjęte już próby. Jest bardzo podobny do implementacji Objective-C.
— Mick MacCallum

Styczeń 2017 swift 2.3: let sVer = NSBundle.mainBundle (). InfoDictionary? ["CFBundleShortVersionString"] as? Ciąg let sBuild = NSBundle.mainBundle (). InfoDictionary? ["CFBundleVersion"] as? String self.myVersionLabel.text = String (format: "Wersja% @ Build% @", sVer !, sBuild!)
— Matthew Ferguson

Odpowiedzi:


167

Co było nie tak ze składnią Swift? To wydaje się działać:

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

2
Dlaczego ten głos został odrzucony? Myślę, że może to być bardziej naturalne, letale poza tym wygląda poprawnie.
— Tommy,

Ach, zapomniałem „as String”, więc zmienna przyjęłaby ją jako ciąg. Dziękuję Ci.
— Ken-UbiDex

2
To wydaje się być zepsute w XCode 6 beta 3
— Frédéric Adda

2
To zadziałało dla mnie w Xcode 6 beta 5:let text = NSBundle.mainBundle().infoDictionary["CFBundleVersion"]! as String
— E. Barnes

@Dean Wygląda na to, że zmienili infoDictionary, aby zwracał opcjonalny. Zmieniłem odpowiedź
— Connor

118

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

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

jak widać tutaj .


1
Dostajesz ten sam klucz dwukrotnie, użyj "CFBundleVersion" dla wersji.
— Wydaje

Dzięki @foOg, to była literówka. W rzeczywistości jest odwrotnie: krótka to wersja, a zwykła to kompilacja. Wiem, dziwne.
— Dan Rosenstark

Wersja Swift 3. jeśli niech infoPath = Bundle.main.path (forResource: "Info.plist", ofType: nil), niech infoAttr = try? FileManager.default.attributesOfItem (atPath: infoPath), niech infoDate = infoAttr [.creationDate] as? Data {return infoDate} return Date ()
— Ryan X

18

Do ostatecznej wersji Xcode 6 użyj

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

„?” postać po infoDictionary jest tu ważna


1
Cholera. Z pewnością uwielbiam to całe „opcjonalne ?, rozpakowywanie!” system, jest krystalicznie czysty i łatwy do odczytania!
— Jeroen Bouma

14

Oto prosty sposób na uzyskanie kompilacji i wersji.

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

W przypadku celu C

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

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

Daj mi znać, jeśli jakiś problem. To działa dla mnie.


13

Swifty sposób AppName, AppVersiona 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))."
   }
}

Dlaczego miałbyś rozpakowywać wartości? O ile mi wiadomo, żadna z tych wartości nie może być zerowa
— Michael

@Michael Niektórzy ludzie ZAWSZE rozpakowują wartości opcjonalne. Niektórzy mówią, że masz rację.
— Dan Rosenstark

2
Bundle.mainmiał infoDictionarydla mnie pusty ; może dlatego, że robię to w ramach, a nie w pliku wykonywalnym lub aplikacji? Bundle(for: MyClass.self)zawiera oczekiwane wartości.
— Raphael

7

Szybko zrobiłbym to jako rozszerzenie dla UIApplication, w ten sposób:

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

Następnie możesz po prostu użyć następujących, aby uzyskać wszystko, czego potrzebujesz:

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

7

// Zwraca numer wersji aplikacji

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

// Zwróć numer kompilacji aplikacji

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

6

Swift 5.0

Utworzyłem opakowanie dla Swift 5, aby uzyskać niektóre ciągi znaków związanych z aplikacjami w jednym miejscu we wszystkich moich aplikacjach, o nazwie 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
     }
}

Możesz go używać w ten sposób:

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

W języku Swift wartość nie jest dostępna, używane jest zero. IMO powinieneś zwrócić nil zamiast niestandardowych ciągów znaków zastępczych.
— Luca Angeletti

Dlatego jest to opakowanie: zawsze coś odzyskać. Sytuacja zerowa nie jest tak naprawdę „zniszczona”, nadal istnieje, ale jest już wstępnie załatwiona. W przeciwnym razie musiałbyś zająć się sytuacją „zerową” w innym miejscu aplikacji.
— LukeSideWalker

dzięki ziom. również ostatni nawias klamrowy znajduje się poza blokiem kodu. :)
— Mark Perkins

2
nazwa aplikacji może być równieżCFBundleDisplayName
— gondo

2

Ten kod działa dla Swift 3, Xcode 8:

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

2

W przypadku Swift 3 zamień NSBundle na Bundle, a mainBundle zostanie zastąpiony po prostu przez main.

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

1

[Aktualizacja: Xcode 6.3.1] Wypróbowałem wszystkie powyższe i żadne z nich nie działa w Xcode 6.3.1, ale stwierdziłem, że to działa:

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

1

Inną opcją jest zdefiniowanie w AppDelegate zmiennych:

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

do których można się odwoływać jako zmienne w AppDelegate



0

Wersja 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

Aby uzyskać wynik dla frameworka, którego możesz użyć

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

lub w testach

let version = Bundle(for: <SomeClass>.self).infoDictionary?["CFBundleShortVersionString"] as? String
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.