我有一个带有Azure后端的IOS应用,并希望记录某些事件,例如登录以及正在运行的应用用户的哪个版本。
如何使用Swift返回版本号和内部版本号?
答案 0 :(得分:299)
修改强>
针对Swift 4.2进行了更新
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
修改强>
正如@azdev在Xcode的新版本中指出的那样,你会在尝试我之前的解决方案时遇到编译错误,要解决这个问题,只需按照建议进行编辑就可以使用!来打开捆绑字典!
let nsObject: AnyObject? = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"]
结束修改
只需使用与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
我希望这可以帮助你。
大卫
答案 1 :(得分:263)
我知道这已经得到了回答,但我个人认为这有点清洁:
Swift 3.0:
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
self.labelVersion.text = version
}
Swift< 2.3
if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String {
self.labelVersion.text = version
}
这样,if let版本负责条件处理(在我的情况下设置标签文本),如果infoDictionary或CFBundleShortVersionString为nil,则可选的解包将导致代码被跳过。
答案 2 :(得分:219)
针对Swift 3.0进行了更新
NS
- 前缀现在已经在Swift 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
旧更新的答案
自从我的原始答案以来,我一直在使用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
原始答案
我想改进一些已发布的答案。我写了一篇 类扩展,可以添加到您的工具链中以处理此问题 更合乎逻辑的方式。
extension NSBundle { class var applicationVersionNumber: String { if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"]
为?字符串{ 返回版本 } 返回“版本号不可用” }
class var applicationBuildNumber: String { if let build = NSBundle.mainBundle().infoDictionary?["CFBundleVersion"] as? String { return build } return "Build Number Not Available" } }
现在您可以通过以下方式轻松访问:
let versionNumber = NSBundle.applicationVersionNumber
答案 3 :(得分:62)
我也知道这已经得到了解答,但我结束了以前的答案:
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")"
}
}
用法:
someLabel.text = Bundle.main.releaseVersionNumberPretty
Swift 3.1 :
class func getVersion() -> String {
guard let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else {
return "no version info"
}
return version
}
旧版本:
class func getVersion() -> String {
if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String {
return version
}
return "no version info"
}
因此,如果您想设置标签文本或想要在其他地方使用;
self.labelVersion.text = getVersion()
答案 4 :(得分:29)
Swift 4.0
let version = Bundle.main.infoDictionary!["CFBundleShortVersionString"]!
let build = Bundle.main.infoDictionary!["CFBundleVersion"]!
答案 5 :(得分:26)
我在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
}
}
然后使用它
versionLabel.text = "\(Bundle.main.appName) v \(Bundle.main.versionNumber) (Build \(Bundle.main.buildNumber))"
答案 6 :(得分:16)
对于Swift 3.0,NSBundle无法正常工作,以下代码可以正常运行。
let versionNumberString =
Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")
as! String
仅对于内部版本号,它是:
let buildNumberString =
Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion")
as! String
令人困惑的CFBundleVersion'是在X轴上输入的构建编号,在General-> Identity。
答案 7 :(得分:14)
Xcode 9.4.1 Swift 4.1
请注意使用localizedInfoDictionary来选择捆绑显示名称的正确语言版本。
Listbox
答案 8 :(得分:12)
Xcode 8,Swift 3:
let gAppVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") ?? "0"
let gAppBuild = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") ?? "0"
答案 9 :(得分:11)
将5作为UIApplication扩展
extension UIApplication {
static var release: String {
return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String? ?? "x.x"
}
static var build: String {
return Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String? ?? "x"
}
static var version: String {
return "\(release).\(build)"
}
}
示例用法:
print("release: \(UIApplication.release)")
print("build: \(UIApplication.build)")
print("version: \(UIApplication.version)")
答案 10 :(得分:9)
我的回答(截至2015年8月),鉴于Swift不断发展:
let version = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
答案 11 :(得分:9)
Bundle + Extension.swift(SwiftUI,Swift 5,Xcode 11)
我结合了一些答案中的想法,并进行了扩展:
导入基金会
extension Bundle {
public var appVersionShort: String? {
if let result = infoDictionary?["CFBundleShortVersionString"] as? String {
return result
} else {
return "⚠️"
}
}
public var appVersionLong: String? {
if let result = infoDictionary?["CFBundleVersion"] as? String {
return result
} else {
return "⚠️"
}
}
public var appName: String? {
if let result = infoDictionary?["CFBundleName"] as? String {
return result
} else {
return "⚠️"
}
}
}
SwiftUI示例使用
VStack {
Text("Version: \(Bundle.main.appVersionShort!) (\(Bundle.main.appVersionLong!))")
.font(.subheadline)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
答案 12 :(得分:8)
Swift 4,适用于捆绑软件的扩展程序
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))"
}
}
答案 13 :(得分:6)
看过文档后,我相信以下内容更清晰:
let version =
NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString")
as? String
Source: "使用此方法优于其他访问方法,因为它在有一个可用时返回键的本地化值。"
答案 14 :(得分:6)
Bundle + Extensions.swift
import Foundation
extension Bundle {
var versionNumber: String? {
return infoDictionary?["CFBundleShortVersionString"] as? String
}
var buildNumber: String? {
return infoDictionary?["CFBundleVersion"] as? String
}
var bundleName: String? {
return infoDictionary?["CFBundleName"] as? String
}
}
用法:
someLabel.text = Bundle.main.versionNumber
答案 15 :(得分:5)
对于Swift 1.2来说:
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *redView;
@property (strong, nonatomic) UITextField *textField;
@property (strong, nonatomic) UITapGestureRecognizer *gesture;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.textField = [[UITextField alloc] initWithFrame:CGRectMake(0.f, 0.f, self.redView.frame.size.width, 30.f)];
self.textField.backgroundColor = [UIColor lightGrayColor];
[self.redView addSubview:self.textField];
self.gesture = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(animateRedView:)];
[self.view addGestureRecognizer:self.gesture];
}
- (IBAction)animateRedView:(id)sender
{
[UIView animateWithDuration:.5
delay:0
usingSpringWithDamping:1.2
initialSpringVelocity:5
options:0
animations:^{
CGRect redViewFrame = self.redView.frame;
[self.redView setFrame:CGRectMake((self.view.frame.size.width - redViewFrame.size.width),
redViewFrame.origin.y,
redViewFrame.size.width,
redViewFrame.size.height)];
} completion:^(BOOL finished) {
[self.textField becomeFirstResponder];
}];
}
@end
答案 16 :(得分:4)
斯威夫特3:
版本号
if let versionNumberString = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String { // do something }
内部版本号
if let buildNumberString = Bundle.main.infoDictionary?["CFBundleVersion"] as? String { // do something }
答案 17 :(得分:3)
Swift 4
ref
Bundle.main.infoDictionary![" CFBundleShortVersionString"]
Swift旧语法
func getAppVersion() -> String {
return "\(Bundle.main.infoDictionary!["CFBundleShortVersionString"] ?? "")"
}
答案 18 :(得分:3)
对于 Swift 5 :
func getAppCurrentVersionNumber() -> String {
let nsObject: AnyObject? = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as AnyObject?
return nsObject as! String
}
答案 19 :(得分:2)
public var appVersionNumberString: String {
get {
return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
}
}
答案 20 :(得分:2)
extension UIApplication {
static var appVersion: String {
if let appVersion = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") {
return "\(appVersion)"
} else {
return ""
}
}
static var build: String {
if let buildVersion = NSBundle.mainBundle().objectForInfoDictionaryKey(kCFBundleVersionKey as String) {
return "\(buildVersion)"
} else {
return ""
}
}
static var versionBuild: String {
let version = UIApplication.appVersion
let build = UIApplication.build
var versionAndBuild = "v\(version)"
if version != build {
versionAndBuild = "v\(version)(\(build))"
}
return versionAndBuild
}
}
注意: 如果你没有设置app版本或版本,你应该使用if here,如果你试图使用它会导致崩溃!打开包装。
答案 21 :(得分:1)
对于感兴趣的任何人,github都提供了一个名为SwifterSwift
的漂亮且整洁的库,并且针对每个版本的swift也提供了完整的文档(请参见swifterswift.com)。
使用此库,读取应用程序版本和内部版本号将像这样简单:
import SwifterSwift
let buildNumber = SwifterSwift.appBuild
let version = SwifterSwift.appVersion
答案 22 :(得分:1)
SWIFT 4
//首先通过定义为可选的AnyObject
来获取nsObjectlet nsObject: AnyObject? = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as AnyObject
//然后将对象强制转换为String,但要小心,你可能需要仔细检查nil
let version = nsObject as! String
答案 23 :(得分:1)
这是Swift 3.2的更新版本:
extension UIApplication
{
static var appVersion:String
{
if let appVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")
{
return "\(appVersion)"
}
return ""
}
static var buildNumber:String
{
if let buildNum = Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String)
{
return "\(buildNum)"
}
return ""
}
static var versionString:String
{
return "\(appVersion).\(buildNumber)"
}
}
答案 24 :(得分:1)
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
self.lblAppVersionValue.text = version
}
答案 25 :(得分:1)
我为UIApplication创建了扩展。
extension UIApplication {
static var appVersion: String {
let versionNumber = Bundle.main.infoDictionary?[IdentifierConstants.InfoPlist.versionNumber] as? String
let buildNumber = Bundle.main.infoDictionary?[IdentifierConstants.InfoPlist.buildNumber] as? String
let formattedBuildNumber = buildNumber.map {
return "(\($0))"
}
return [versionNumber,formattedBuildNumber].compactMap { $0 }.joined(separator: " ")
}
}
struct IdentifierConstants {
struct InfoPlist {
static let versionNumber = "CFBundleShortVersionString"
static let buildNumber = "CFBundleVersion"
}
}
答案 26 :(得分:0)
Swift 5.3
let infoDictionaryKey = kCFBundleVersionKey as String
guard let currentVersion = Bundle.main.object(forInfoDictionaryKey: infoDictionaryKey) as? String
else { fatalError("Expected to find a bundle version in the info dictionary") }
答案 27 :(得分:0)
简单的实用程序功能可将应用程序版本返回为 Int
func getAppVersion() -> Int {
if let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
let appVersionClean = appVersion.replacingOccurrences(of: ".", with: "", options: NSString.CompareOptions.literal, range:nil)
if let appVersionNum = Int(appVersionClean) {
return appVersionNum
}
}
return 0
}
答案 28 :(得分:0)
OP要求提供版本号和内部版本号。不幸的是,大多数答案都没有提供这两个选项。此外,其他人添加了不必要的扩展方法。这很简单,可以解决OP的问题:
// Example output: "1.0 (234)"
private func versionAndBuildNumber() -> String {
let versionNumber = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
if let versionNumber = versionNumber, let buildNumber = buildNumber {
return "\(versionNumber) (\(buildNumber))"
} else if let versionNumber = versionNumber {
return versionNumber
} else if let buildNumber = buildNumber {
return buildNumber
} else {
return ""
}
}
答案 29 :(得分:0)
您现在可以为此使用常量,而不必像以前一样使用字符串类型的代码,这使事情变得更加方便。
var appVersion: String {
return Bundle.main.infoDictionary![kCFBundleVersionKey as String] as! String
}
答案 30 :(得分:0)
这是我用来确定是否显示“应用程序已更新”页面的功能。它返回内部版本号,我正在将其转换为Int:
if let version: String = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
guard let intVersion = Int(version) else { return }
if UserDefaults.standard.integer(forKey: "lastVersion") < intVersion {
print("need to show popup")
} else {
print("Don't need to show popup")
}
UserDefaults.standard.set(intVersion, forKey: "lastVersion")
}
如果以前从未使用过,它将返回比当前内部版本号低的0。要不向新用户显示此屏幕,只需在首次登录后或入职完成后添加内部版本号即可。
答案 31 :(得分:0)
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
lblVersion.text = "Version \(version)"
}
答案 32 :(得分:-1)
对于 Swift 5.0 :
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as! String
答案 33 :(得分:-1)
Swift 2.0
//First get the nsObject by defining as an optional anyObject
let nsObject: AnyObject? = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"]
let version = nsObject as! String