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

IosSwift

Ios Problem Overview


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.

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

Ios Solutions


Solution 1 - Ios

EDIT

Updated for 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 !

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

End Edit

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

//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

Solution 2 - Ios

Updated for 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:

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


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

Solution 3 - Ios

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

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
}

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.

Solution 4 - Ios

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:

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()

Solution 5 - Ios

For Swift 4.0

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

Solution 6 - Ios

I made an Extension on 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))"

Solution 7 - Ios

Swift 5 as UIApplication extension

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

example use:

print("release: \(UIApplication.release)")
print("build: \(UIApplication.build)")
print("version: \(UIApplication.version)")

Solution 8 - Ios

Bundle+Extension.swift (SwiftUI, Swift 5, Xcode 11)

I combined ideas from a few answers, and extended a bit:

  • a SwiftUI example
  • Displays a warning triangle emoticon (rather than crashing the app) if the key is missing from the Info.plist

import Foundation

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 example use

VStack {

     Text("Version: \(Bundle.main.appVersionShort!) (\(Bundle.main.appVersionLong!))")
                    .font(.subheadline)
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
}

Solution 9 - Ios

I created an extension for 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"
    }
}

Solution 10 - Ios

2021, Swift 5

extension Bundle {
    public var appName: String { getInfo("CFBundleName")  }
    public var displayName: String {getInfo("CFBundleDisplayName")}
    public var language: String {getInfo("CFBundleDevelopmentRegion")}
    public var identifier: String {getInfo("CFBundleIdentifier")}
    public var copyright: String {getInfo("NSHumanReadableCopyright").replacingOccurrences(of: "\\\\n", with: "\n") }
    
    public var appBuild: String { getInfo("CFBundleVersion") }
    public var appVersionLong: String { getInfo("CFBundleShortVersionString") }
    //public var appVersionShort: String { getInfo("CFBundleShortVersion") }
    
    fileprivate func getInfo(_ str: String) -> String { infoDictionary?[str] as? String ?? "⚠️" }
}

usage (SwiftUI sample):

    Text("Ver: \(Bundle.main.appVersionLong) (\(Bundle.main.appBuild)) ")
    
    Text(Bundle.main.copyright)
        .font(.system(size: 10, weight: .thin))
        .multilineTextAlignment(.center)

Bonus: Copyright supports \n symbols!

enter image description here

Solution 11 - Ios

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

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 build number as entered in Xcode on General->Identity.

Solution 12 - Ios

Xcode 9.4.1 Swift 4.1

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

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

Solution 13 - Ios

Xcode 8, Swift 3:

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

Solution 14 - Ios

Swift 4, useful Extension for 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))"
	}
}

Solution 15 - Ios

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

Usage:

someLabel.text = Bundle.main.versionNumber

Solution 16 - Ios

OP asked for both version number and build number. Unfortunately most of the answers don't provide both of those options. Additionally, others add unnecessary extension methods. Here's one that's pretty simple and solves OP's problem:

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

Solution 17 - Ios

My answer (as at Aug 2015), given Swift keeps evolving:

let version = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String

Solution 18 - Ios

Having looked at the documentation, I believe that the following is cleaner:

let version = 
NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") 
as? String

Source: "Use of this method is preferred over other access methods because it returns the localized value of a key when one is available."

Solution 19 - Ios

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

Solution 20 - Ios

For Swift 5.0 :

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

Solution 21 - Ios

For Swift 1.2 it's:

let version = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"] as! String
let build = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String

Solution 22 - Ios

Swift 3:

Version Number

if let versionNumberString = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String { // do something }

Build number

if let buildNumberString = Bundle.main.infoDictionary?["CFBundleVersion"] as? String { // do something }

Solution 23 - Ios

Here's an updated version for 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)"
	}
}

Solution 24 - Ios

Swift 4

func getAppVersion() -> String {
    return "\(Bundle.main.infoDictionary!["CFBundleShortVersionString"] ?? "")"
}

> Bundle.main.infoDictionary!["CFBundleShortVersionString"]

Swift old syntax

let appVer: AnyObject? = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"]

Solution 25 - Ios

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

Attention: You should use if let here in case that the app version or build is not set which will lead to crash if you try to use ! to unwrap.

Solution 26 - Ios

public var appVersionNumberString: String {
    get {
        return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
    }
}

Solution 27 - Ios

Update for Swift 5

here's a function i'm using to decide whether to show an "the app updated" page or not. It returns the build number, which i'm converting to an 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")
    }

If never used before it will return 0 which is lower than the current build number. To not show such a screen to new users, just add the build number after the first login or when the on-boarding is complete.

Solution 28 - Ios

You can now use a constant for this, rather than having to use stringly-typed code like before, which makes things even more convenient.

var appVersion: String {
    return Bundle.main.infoDictionary![kCFBundleVersionKey as String] as! String
}

Solution 29 - Ios

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

Solution 30 - Ios

SWIFT 4

//First get the nsObject by defining as an optional AnyObject

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

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

let version = nsObject as! String

Solution 31 - Ios

for anyone interested, there's a nice and neat library called SwifterSwift available at github and also fully documented for every version of swift (see swifterswift.com).

using this library, reading app version and build number would be as easy as this:

import SwifterSwift

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

Solution 32 - Ios

Simple utility function to return App version as 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
    }

Solution 33 - Ios

For 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

Solution 34 - Ios

if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
        lblVersion.text = "Version \(version)"
        
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Question&#216;yvind VikView Question on Stackoverflow
Solution 1 - IosDavidView Answer on Stackoverflow
Solution 2 - IosBlake MerrymanView Answer on Stackoverflow
Solution 3 - IosTimothy TrippView Answer on Stackoverflow
Solution 4 - IosGunhanView Answer on Stackoverflow
Solution 5 - IosIryna BatvinaView Answer on Stackoverflow
Solution 6 - IosCarmenView Answer on Stackoverflow
Solution 7 - IosziligyView Answer on Stackoverflow
Solution 8 - IosGary W. LongsineView Answer on Stackoverflow
Solution 9 - IosSebastian BoldtView Answer on Stackoverflow
Solution 10 - IosAndrewView Answer on Stackoverflow
Solution 11 - IosTejasView Answer on Stackoverflow
Solution 12 - IosHugo FView Answer on Stackoverflow
Solution 13 - IosCrashalotView Answer on Stackoverflow
Solution 14 - IosmaslovsaView Answer on Stackoverflow
Solution 15 - IosGiangView Answer on Stackoverflow
Solution 16 - IosSensefulView Answer on Stackoverflow
Solution 17 - IosCharlie SeligmanView Answer on Stackoverflow
Solution 18 - IosDaniel ArmyrView Answer on Stackoverflow
Solution 19 - IosVyacheslavBakinkskiyView Answer on Stackoverflow
Solution 20 - IosDbyView Answer on Stackoverflow
Solution 21 - IosMichael SamoylovView Answer on Stackoverflow
Solution 22 - IosjasonnoahchoiView Answer on Stackoverflow
Solution 23 - IosBadmintonCatView Answer on Stackoverflow
Solution 24 - IosHarshil KotechaView Answer on Stackoverflow
Solution 25 - IosfutantanView Answer on Stackoverflow
Solution 26 - IosMohammad RazipourView Answer on Stackoverflow
Solution 27 - IosGiovanni PalusaView Answer on Stackoverflow
Solution 28 - IosTheNeilView Answer on Stackoverflow
Solution 29 - IosDavender VermaView Answer on Stackoverflow
Solution 30 - IosPrabhat KaseraView Answer on Stackoverflow
Solution 31 - IosMFAView Answer on Stackoverflow
Solution 32 - IosTiago MendesView Answer on Stackoverflow
Solution 33 - IosAadi007View Answer on Stackoverflow
Solution 34 - Iosishwar lal janwaView Answer on Stackoverflow