ios 如何使用 Swift 获取应用程序版本和内部版本号?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25965239/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:41:03  来源:igfitidea点击:

How do I get the App version and build number using Swift?

iosswift

提问by ?yvind Vik

I have an IOS app with an Azure back-end, and would like to log certain events, like logins and which versions of the app users are running.

我有一个带有 Azure 后端的 IOS 应用程序,并且想记录某些事件,例如登录以及用户正在运行的应用程序版本。

How can I return the version and build number using Swift?

如何使用 Swift 返回版本和内部版本号?

回答by David

EDIT

编辑

Updated for Swift 4.2

为 Swift 4.2 更新

let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String

EDIT

编辑

As pointed out by @azdev on the new version of Xcode you will get a compile error for trying my previous solution, to solve this just edit it as suggested to unwrap the bundle dictionary using a !

正如@azdev 在新版本的 Xcode 上指出的那样,尝试我以前的解决方案时会出现编译错误,要解决这个问题,只需按照建议编辑它以使用 !

let nsObject: AnyObject? = Bundle.main.infoDictionary!["CFBundleShortVersionString"]

End Edit

结束编辑

Just use the same logic than in Objective-C but with some small changes

使用与 Objective-C 相同的逻辑,但有一些小的变化

//First get the nsObject by defining as an optional anyObject
let nsObject: AnyObject? = NSBundle.mainBundle().infoDictionary["CFBundleShortVersionString"]

//Then just cast the object as a String, but be careful, you may want to double check for nil
let version = nsObject as! String

I hope this helps you out.

我希望这能够帮到你。

David

大卫

回答by Timothy Tripp

I know this has already been answered but personally I think this is a little cleaner:

我知道这已经得到了回答,但我个人认为这更简洁:

Swift 3.0:

斯威夫特 3.0:

 if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
    self.labelVersion.text = version
}

Swift <2.3

斯威夫特 <2.3

if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String {
    self.labelVersion.text = version
}

This way, the if let version takes care of the conditional processing (setting the label text in my case) and if infoDictionary or CFBundleShortVersionString are nil the optional unwrapping will cause the code to be skipped.

这样, if let 版本负责条件处理(在我的情况下设置标签文本),如果 infoDictionary 或 CFBundleShortVersionString 为零,可选的解包将导致代码被跳过。

回答by Blake Merryman

Updated for Swift 3.0

为 Swift 3.0 更新

The NS-prefixes are now gone in Swift 3.0 and several properties/methods have changed names to be more Swifty. Here's what this looks like now:

NS现在-prefixes都走了斯威夫特3.0和几个属性/方法已经改变名称,以更加SWIFTY。这是现在的样子:

extension Bundle {
    var releaseVersionNumber: String? {
        return infoDictionary?["CFBundleShortVersionString"] as? String
    }
    var buildVersionNumber: String? {
        return infoDictionary?["CFBundleVersion"] as? String
    }
}

Bundle.main.releaseVersionNumber
Bundle.main.buildVersionNumber

Old Updated Answer

旧的更新答案

I've been working with Frameworks a lot since my original answer, so I wanted to update my solution to something that is both simpler and much more useful in a multi-bundle environment:

extension NSBundle {

    var releaseVersionNumber: String? {
        return self.infoDictionary?["CFBundleShortVersionString"] as? String
    }

    var buildVersionNumber: String? {
        return self.infoDictionary?["CFBundleVersion"] as? String
    }

}

Now this extension will be useful in apps to identify both the main bundle and any other included bundles (such as a shared framework for extension programming or third frameworks like AFNetworking), like so:

NSBundle.mainBundle().releaseVersionNumber
NSBundle.mainBundle().buildVersionNumber

// or...

NSBundle(URL: someURL)?.releaseVersionNumber
NSBundle(URL: someURL)?.buildVersionNumber

自从我的原始答案以来,我一直在使用 Frameworks,所以我想将我的解决方案更新为在多捆绑环境中更简单且更有用的解决方案:

extension NSBundle {

    var releaseVersionNumber: String? {
        return self.infoDictionary?["CFBundleShortVersionString"] as? String
    }

    var buildVersionNumber: String? {
        return self.infoDictionary?["CFBundleVersion"] as? String
    }

}

现在这个扩展将在应用程序中用于识别主包和任何其他包含的包(例如用于扩展编程的共享框架或像 AFNetworking 这样的第三框架),如下所示:

NSBundle.mainBundle().releaseVersionNumber
NSBundle.mainBundle().buildVersionNumber

// or...

NSBundle(URL: someURL)?.releaseVersionNumber
NSBundle(URL: someURL)?.buildVersionNumber


Original Answer

原答案

I wanted to improve on some of the answers already posted. I wrote a class extension that can be added to your tool chain to handle this in a more logical fashion.

extension NSBundle {

class var applicationVersionNumber: String {
    if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"]

as? String { return version } return "Version Number Not Available" }

class var applicationBuildNumber: String {
    if let build = NSBundle.mainBundle().infoDictionary?["CFBundleVersion"] as? String {
        return build
    }
    return "Build Number Not Available"
}

}

So now you can access this easily by:

let versionNumber = NSBundle.applicationVersionNumber

我想改进一些已经发布的答案。我编写了一个类扩展,可以将其添加到您的工具链中,以更合乎逻辑的方式处理此问题。

extension NSBundle {

class var applicationVersionNumber: String {
    if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"]

作为?String { return version } return "版本号不可用" }

class var applicationBuildNumber: String {
    if let build = NSBundle.mainBundle().infoDictionary?["CFBundleVersion"] as? String {
        return build
    }
    return "Build Number Not Available"
}

}

所以现在您可以通过以下方式轻松访问它:

let versionNumber = NSBundle.applicationVersionNumber

回答by Gunhan

I also know this has already been answered but I wrapped up the previous answers:

我也知道这已经得到了回答,但我总结了以前的答案:

(*)Updated for extensions

(*) 更新扩展

extension Bundle {
    var releaseVersionNumber: String? {
        return infoDictionary?["CFBundleShortVersionString"] as? String
    }
    var buildVersionNumber: String? {
        return infoDictionary?["CFBundleVersion"] as? String
    }
    var releaseVersionNumberPretty: String {
        return "v\(releaseVersionNumber ?? "1.0.0")"
    }
}

Usage:

用法:

someLabel.text = Bundle.main.releaseVersionNumberPretty

@Deprecated: Old answers

@已弃用:旧答案

Swift 3.1:

斯威夫特 3.1

class func getVersion() -> String {
    guard let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else {
        return "no version info"
    }
    return version
}

For older versions:

对于旧版本

class func getVersion() -> String {
    if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String {
        return version
    }
    return "no version info"
}

So if you want to set label text or want to use somewhere else;

所以如果你想设置标签文本或者想在其他地方使用;

self.labelVersion.text = getVersion()

回答by Iryna Batvina

For Swift 4.0

对于Swift 4.0

let version = Bundle.main.infoDictionary!["CFBundleShortVersionString"]!
let build = Bundle.main.infoDictionary!["CFBundleVersion"]!

回答by carmen_munich

I made an Extension on Bundle

我在 Bundle 上做了一个扩展

extension Bundle {

    var appName: String {
        return infoDictionary?["CFBundleName"] as! String
    }

    var bundleId: String {
        return bundleIdentifier!
    }

    var versionNumber: String {
        return infoDictionary?["CFBundleShortVersionString"] as! String 
    }

    var buildNumber: String {
        return infoDictionary?["CFBundleVersion"] as! String
    }

}

and then use it

然后使用它

versionLabel.text = "\(Bundle.main.appName) v \(Bundle.main.versionNumber) (Build \(Bundle.main.buildNumber))"

回答by Tejas

For Swift 3.0 NSBundle doesn't work, Following code works perfectly.

对于 Swift 3.0 NSBundle 不起作用,以下代码完美运行。

let versionNumberString =
      Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")
          as! String

and for just the build number, it is:

对于内部版本号,它是:

let buildNumberString =
      Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion")
          as! String

Confusingly 'CFBundleVersion' is the buildnumber as entered in Xcode on General->Identity.

令人困惑的是,“CFBundleVersion”是在 Xcode 中在 General->Identity 上输入的内部版本号。

回答by Hugo F

Xcode 9.4.1 Swift 4.1

Xcode 9.4.1 斯威夫特 4.1

Note the use of localizedInfoDictionary to pick up the right language version of the bundle display name.

请注意使用 localizedInfoDictionary 来选择包显示名称的正确语言版本。

var displayName: String?
var version: String?
var build: String?

override func viewDidLoad() {
    super.viewDidLoad()

    // Get display name, version and build

    if let displayName = Bundle.main.localizedInfoDictionary?["CFBundleDisplayName"] as? String {
        self.displayName = displayName
    }
    if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
        self.version = version
    }
    if let build = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
        self.build = build
    }
}

回答by Crashalot

Xcode 8, Swift 3:

Xcode 8,斯威夫特 3:

let gAppVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") ?? "0"
let gAppBuild = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") ?? "0"

回答by maslovsa

Swift 4, useful Extension for Bundle

Swift 4,有用的 Bundle 扩展

import Foundation

public extension Bundle {

    public var shortVersion: String {
        if let result = infoDictionary?["CFBundleShortVersionString"] as? String {
            return result
        } else {
            assert(false)
            return ""
        }
    }

    public var buildVersion: String {
        if let result = infoDictionary?["CFBundleVersion"] as? String {
            return result
        } else {
            assert(false)
            return ""
        }
    }

    public var fullVersion: String {
        return "\(shortVersion)(\(buildVersion))"
    }
}