我有一个带有Azure后端的IOS应用程序,并且想记录某些事件,例如登录名和正在运行的应用程序版本。
如何使用Swift返回版本和内部版本号?
我有一个带有Azure后端的IOS应用程序,并且想记录某些事件,例如登录名和正在运行的应用程序版本。
如何使用Swift返回版本和内部版本号?
Answers:
编辑
为Swift 4.2更新
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
编辑
正如@azdev在新版本的Xcode上指出的那样,尝试我以前的解决方案时会遇到编译错误,要解决此问题,只需按照建议的方法对其进行编辑即可使用!来解开bundle字典。
let nsObject: AnyObject? = Bundle.main.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
我希望这能够帮到你。
大卫
infoDictionary
应该使用展开!
。这是我正在使用的内容,放置在Globals.swift文件中:let appVersion = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as String
let appVersion = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
我知道已经回答了这个问题,但就我个人而言,我认为这更干净一些:
Swift 3.0:
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
self.labelVersion.text = version
}
迅捷<2.3
if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String {
self.labelVersion.text = version
}
这样,if let版本负责条件处理(在我的情况下设置标签文本),并且如果infoDictionary或CFBundleShortVersionString为nil,则可选的展开将导致代码被跳过。
self.labelVersion.text
是可选类型,因此您可以直接分配NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String
let
,只是想知道为什么会需要它。谢谢!
为Swift 3.0更新
在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
旧的更新答案
自从我最初的回答以来,我一直在使用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
我也知道这已经得到回答,但是我总结了以前的答案:
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()
对于Swift 4.0
let version = Bundle.main.infoDictionary!["CFBundleShortVersionString"]!
let build = Bundle.main.infoDictionary!["CFBundleVersion"]!
我做了捆绑扩展
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))"
对于Swift 3.0 NSBundle不起作用,以下代码可完美工作。
let versionNumberString =
Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")
as! String
对于内部版本号,它是:
let buildNumberString =
Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion")
as! String
令人困惑的是,“ CFBundleVersion”是在“常规”- >“身份”上的Xcode中输入的内部版本号。
Xcode 9.4.1 Swift 4.1
请注意,使用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
}
}
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))"
}
}
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
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 ""
}
}
我为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"
}
}
看完文档,我相信以下内容更干净:
let version =
NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString")
as? String
来源:“与其他访问方法相比,首选使用此方法,因为它会在密钥可用时返回密钥的本地化值。”
对于Swift 1.2,它是:
let version = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"] as! String
let build = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
斯威夫特3:
版本号
if let versionNumberString = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String { // do something }
内部编号
if let buildNumberString = Bundle.main.infoDictionary?["CFBundleVersion"] as? String { // do something }
斯威夫特4
func getAppVersion() -> String {
return "\(Bundle.main.infoDictionary!["CFBundleShortVersionString"] ?? "")"
}
Bundle.main.infoDictionary![“ CFBundleShortVersionString”]
迅捷的旧语法
let appVer: AnyObject? = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"]
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
}
}
注意:如果未设置应用程序版本或内部版本,则应在此处使用,如果尝试使用,将导致崩溃!打开。
这是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)"
}
}
public var appVersionNumberString: String {
get {
return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
}
}
SWIFT 4
//首先通过定义为可选的AnyObject获得nsObject
let nsObject: AnyObject? = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as AnyObject
//然后将对象强制转换为字符串,但是要小心,您可能需要仔细检查nil
let version = nsObject as! String
简单的实用程序功能可将App版本返回为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
}
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
self.lblAppVersionValue.text = version
}
对于任何感兴趣的人,SwifterSwift
在github上都有一个不错的,整洁的库,该库也为swift的每个版本提供了完整的文档(请参阅swifterswift.com)。
使用此库,读取应用程序版本和内部版本号将像下面这样简单:
import SwifterSwift
let buildNumber = SwifterSwift.appBuild
let version = SwifterSwift.appVersion
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
lblVersion.text = "Version \(version)"
}
这是我用来决定是否显示“应用程序更新”页面的功能。它返回内部版本号,我将其转换为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。要不向新用户显示此屏幕,只需在首次登录后或完成注册后添加内部版本号。