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

如何使用Swift返回版本和构建号?


当前回答

我为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: " ")
    }
}

enum Constants {
    enum InfoPlist {
        static let versionNumber = "CFBundleShortVersionString"
        static let buildNumber = "CFBundleVersion"
    }
}

其他回答

对于Swift 3.0 NSBundle不工作,下面的代码工作完美。

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

对于版本号,它是:

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

令人困惑的'CFBundleVersion'是在Xcode General->Identity中输入的构建号。

针对Swift 3.0更新

在Swift 3.0中,ns前缀已经没有了,一些属性/方法的名称已经更改为更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

更新答案

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


原来的答案

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

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

对于任何感兴趣的人,在github上有一个漂亮而整洁的库叫做SwifterSwift,它也有完整的swift版本文档(参见swifterswift.com)。

使用这个库,读取应用版本和构建号就像这样简单:

import SwifterSwift

let buildNumber = SwifterSwift.appBuild
let version = SwifterSwift.appVersion

捆绑+扩展.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