使用Swift获取版本和构建信息


92

我试图访问Main NSBundle以检索版本和构建信息。问题是,我想快速尝试它,我知道如何使用Objective-C检索它Build.text = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];。但是我不知道从哪里开始,我试图用新的语法写它毫无用处。


2
显示您已经进行的尝试。它与Objective-C的实现非常相似。
Mick MacCallum 2014年

2017年1月Swift 2.3:让sVer = NSBundle.mainBundle()。infoDictionary?[“ CFBundleShortVersionString”]设置为?字符串让sBuild = NSBundle.mainBundle()。infoDictionary?[“ CFBundleVersion”]为?字符串self.myVersionLabel.text =字符串(格式:“版本%@ Build%@”,sVer!,sBuild!)
Matthew Ferguson

Answers:


167

Swift语法出了什么问题?这似乎可行:

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

2
为什么这被否决?我想它可能更自然,let但否则看起来是正确的。
汤米2014年

啊,我忘记了“ as String”,因此变量会将其接受为字符串。谢谢。
Ken-UbiDex 2014年

2
这似乎是6的β3的XCode断
弗雷德里克阿达

2
这在Xcode 6 beta 5中对我有用:let text = NSBundle.mainBundle().infoDictionary["CFBundleVersion"]! as String
E. Barnes

@Dean好像他们将infoDictionary更改为返回可选内容。我已编辑答案
Connor 2014年

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,这是一个错字。实际上它是倒退的:简短的是版本,常规的是构建。很奇怪,我知道。
Dan Rosenstark 2015年

Swift 3版本。如果让infoPath = Bundle.main.path(forResource:“ Info.plist”,ofType:nil),让infoAttr =尝试?FileManager.default.attributesOfItem(atPath:infoPath),让infoDate = infoAttr [.creationDate]为?日期{return infoDate} return Date()
Ryan X

18

对于Xcode 6的最终版本,请使用

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

“?” infoDictionary之后的字符在这里很重要


1
该死的。我肯定会喜欢整个“可选?解开!” 系统,非常清晰,易于阅读!
Jeroen Bouma 2015年

14

这是获取构建和版本的简单方法。

对于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)
   }

对于目标C

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

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

让我知道是否有任何问题。这对我有用。


13

对于SWIFTY方式AppNameAppVersionBuildNumber...

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

@Michael有些人总是打开可选值。有人说你是对的。
Dan Rosenstark '16

2
Bundle.maininfoDictionary为我空了 也许是因为我是从框架而不是可执行文件或应用程序中进行的?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,您应该返回nil而不是自定义占位符字符串。
Luca Angeletti

这就是为什么要包装的原因:总是拿回东西。零位并没有真正被“销毁”,它仍然存在,但是已经被预先处理。否则,您将不得不在应用程序的其他位置处理“ nil”情况。
LukeSideWalker

谢谢芽。同样,您最后的花括号在代码块之外。:)
马克·帕金斯

2
应用名称也可以是CFBundleDisplayName
gondo

2

这段代码适用于Swift 3,Xcode 8:

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


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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.