Отримання інформації про версію та збірку за допомогою Swift


92

Я намагаюся отримати доступ до Основного NSBundle, щоб отримати інформацію про версію та збірку. Справа в тому, що я хочу спробувати це швидко, я знаю, як отримати його в Objective-C за допомогою Build.text = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];. Але я не знаю, з чого почати швидко, я намагався написати це у новому синтаксисі безрезультатно.


2
Покажіть вже зроблені вами спроби. Це дуже схоже на реалізацію Objective-C.
Mick MacCallum

Січень 2017 р. Швидкий 2.3: let sVer = NSBundle.mainBundle (). InfoDictionary? ["CFBundleShortVersionString"] як? Рядок нехай sBuild = NSBundle.mainBundle (). InfoDictionary? ["CFBundleVersion"] як? Рядок self.myVersionLabel.text = Рядок (формат: "Версія% @ Build% @", sVer !, sBuild!)
Метью Фергюсон,

Відповіді:


167

Що було не так із синтаксисом Swift? Здається, це працює:

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

2
Чому це було проти? Думаю, це може бути більш природно, letале в іншому випадку це виглядає правильно.
Tommy

Ах, я забув "як рядок", щоб змінна прийняла його як рядок. Дякую.
Ken-UbiDex

2
Здається, це зламано з XCode 6 beta 3
Фредерік Адда

2
Це спрацювало для мене в Xcode 6 beta 5:let text = NSBundle.mainBundle().infoDictionary["CFBundleVersion"]! as String
Е. Барнс

@Dean Схоже, вони змінили infoDictionary, щоб повернути необов’язковий. Я відредагував відповідь
Коннор,

118

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

Версія 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)"
}

як видно тут .


1
Ви отримуєте той самий ключ двічі, для версії слід використовувати "CFBundleVersion". Думаю, це копія / минула помилка :)
foOg

Дякую @foOg, це була помилка. Насправді це назад: коротка - версія, звичайна - збірка. Дивно, я знаю.
Ден Розенстарк,

Версія Swift 3. якщо нехай infoPath = Bundle.main.path (forResource: "Info.plist", ofType: nil), нехай infoAttr = спробувати? FileManager.default.attributesOfItem (atPath: infoPath), нехай infoDate = infoAttr [.creationDate] як? Дата {return infoDate} дата повернення ()
Райан X

18

Для остаточного випуску Xcode 6 використовуйте

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

Значок "?" символ після infoDictionary тут важливий


1
Блін. Я справді люблю все це "необов’язково ?, розгортай!" система, вона кристально чиста і така легка для читання!
Jeroen Bouma

14

Ось простий спосіб отримати Build та версію.

Для 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)
   }

Для Цілі С

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

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

Повідомте мене, якщо є якась проблема Це працює для мене.


13

Швидкий спосіб AppName, AppVersionі 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))."
   }
}

Навіщо вам потрібно розгортати значення? Наскільки мені відомо, неможливо, щоб будь-яке з цих значень було нульовим
Майкл

@Michael деякі люди ЗАВЖДИ розгортають необов'язкові значення. Деякі люди кажуть, що ти маєш рацію.
Dan Rosenstark

2
Bundle.mainмав порожній infoDictionaryдля мене; може тому, що я роблю це в рамках, а не виконуваному файлі чи програмі? Bundle(for: MyClass.self)містить очікувані значення.
Рафаель

7

Швидко, я б зробив це як розширення для UIApplication, наприклад:

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

Тоді ви можете просто використовувати наступне, щоб отримати все необхідне:

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

7

// Повертає номер версії програми

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

// Повернути номер збірки програми

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

6

Свіфт 5.0

Я створив обгортку для Swift 5, щоб отримувати рядки, пов’язані з додатками, в одному місці у всіх моїх програмах, що називається 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
     }
}

Ви можете використовувати його так:

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

Коли в Swift значення недоступне, використовується nil. IMO ви повинні повернути нуль замість користувацьких рядків заповнювачів.
Лука Анжелетті,

Ось чому це обгортка: Завжди отримувати щось назад. Нульова ситуація насправді не "знищена", вона все ще є, але вже попередньо оброблена. В іншому випадку вам доведеться обробляти ситуацію "нуль" в іншому місці вашого додатка.
LukeSideWalker

дякую бутон. також, остання фігурна дужка знаходиться поза блоком коду. :)
Марк Перкінс

2
Назва програми також може бутиCFBundleDisplayName
гондо

2

Цей код працює для Swift 3, Xcode 8:

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

2

Для Swift 3, Замініть NSBundle на Bundle, а mainBundle замінено просто на main.

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

1

[Оновлення: Xcode 6.3.1] Я спробував усе вищезазначене, і жодна з цих робіт не працює в Xcode 6.3.1, але я виявив, що це робить:

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

1

Інший варіант - визначити в AppDelegate змінні:

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

на які можна посилатися як на змінні в AppDelegate



0

Версія 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

Щоб отримати результат для фреймворку, ви можете використовувати

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

або в тестах

let version = Bundle(for: <SomeClass>.self).infoDictionary?["CFBundleShortVersionString"] as? String
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.