How to programmatically display version/build number of target in iOS app?

65,794

Solution 1

There are 2 Numbers!

The marketing release number is for the customers, called version number. It starts with 1.0 and goes up for major updates to 2.0, 3.0, for minor updates to 1.1, 1.2 and for bug fixes to 1.0.1, 1.0.2 . This number is oriented about releases and new features. It does not have to stop at 9, 1.11.23 is a reasonable version number.

The build number is mostly the internal number of builds that have been made until then. But some use other numbers like the branch number of the repository or its commit number. This number should be unique to distinguish the different builds, which only have minor incremental changes.


To get the version number:

Objective-C:

NSString * appVersionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];

Swift < 3.0:

let appVersionString: String = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") as! String

Swift 3.0+ (tested with 5.0):

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

To get the build number:

Objective-C:

NSString * appBuildString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];

Swift < 3.0:

let buildNumber: String = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleVersion") as! String

Swift 3.0+ (tested until 5.0):

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

If you want both in one:

First use the above lines and then the following one.

Objective-C:

NSString * versionBuildString = [NSString stringWithFormat:@"Version: %@ (%@)", appVersionString, appBuildString];

Swift (tested until 5.0):

let versionAndBuildNumber: String = "\(appVersionString) (\(buildNumber))"

Notes:

The values in the main bundle are not always present, for example in a command line application there is no CFBundleShortVersionString or CFBundleVersion, so the methods will return nil and it will crash because in the code it makes a incorrect downcast. But in normal Cocoa iOS and Mac apps these values are defined and will not be deleted.

This is tested with Xcode Version 7.3 (7D175). The build number is often written in parenthesis / braces. The build number is in hexadecimal or decimal.

buildandversion


In Xcode you can auto-increment the build number as a decimal number by placing the following in the Run script build phase in the project settings

#!/bin/bash    
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"

For hexadecimal build number use this script

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$((0x$buildNumber)) 
buildNumber=$(($buildNumber + 1)) 
buildNumber=$(printf "%X" $buildNumber)
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"

For Xcode do the following:

Step 1

step1

Step 2

step2

Step 3

step3

Solution 2

You don't need to change anything in your project or Xcode. Here's the Swift version for both separately:

let versionNumber = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") as! String
let buildNumber = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleVersion") as! String

It's included in this repo, check it out:

https://github.com/goktugyil/EZSwiftExtensions

Solution 3

Here same code for Swift 3:

let versionNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
let buildNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String

Solution 4

Programmatically display version and build number - Swift 4.0

let versionNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") ?? "1.0"

let buildNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") ?? "1.0"            

let versionAndBuildNumber = "Ver #\(versionNumber) ( Build #\(buildNumber) )"

Solution 5

I made an extension for Bundle so it will be easy to use

extension Bundle {
    var releaseVersionNumber: String? {
        return infoDictionary?["CFBundleShortVersionString"] as? String
    }

    var buildVersionNumber: String? {
        return infoDictionary?["CFBundleVersion"] as? String
    }

    var applicationName: String {
        return infoDictionary?["CFBundleDisplayName"] as? String ?? "ADKATech"
    }

    var applicationReleaseDate: String {
        return infoDictionary?["ApplicationReleaseDate"] as? String ?? Date().description
    }

    var applicationReleaseNumber: Int {
        return infoDictionary?["ApplicationReleaseNumber"] as? Int ?? 0
    }

    var releaseVersionNumberPretty: String {
        return "\(releaseVersionNumber ?? "1.0.0")"
    }

    var buildVersionNumberPretty: String {
        return "\(buildVersionNumber ?? "1")"
    }
}
Share:
65,794
slim
Author by

slim

iOS swift iphone ipad android hockey linux suse commandline c# python java skateboarding developer web css mobile php

Updated on April 21, 2020

Comments

  • slim
    slim about 4 years

    How can I programmatically get the value of the target version, like in the image below?

    As seen in the Properties window of the target of my Xcode project. I want to display this in the splash screen of my app so I know which version the people are currently using?

  • justinkoh
    justinkoh over 11 years
    Just to add for the above example, "CFBundleVersion" is the Build=300, "CFBundleShortVersionString" is the Version=0.41. Viktor's answer should be the correct answer.
  • hashier
    hashier over 10 years
    I had problems with hex numbers once. Apple states to use integers: developer.apple.com/library/ios/documentation/general/Refere‌​nce/…
  • igrek
    igrek over 8 years
    Do you know if there are there any string constants for @"CFBundleShortVersionString" and @"CFBundleVersion" ?
  • Esqarrouth
    Esqarrouth over 8 years
    which answer? i dont see it
  • Daniel Galasko
    Daniel Galasko over 8 years
    There's only one answer, it's in his second paragraph
  • Esqarrouth
    Esqarrouth over 8 years
    Yeah, 1. Theres too much noise and not much signal in his answer. 2. This is swift, that is objective-c. 3. Thats from ios5 era
  • Sam Ballantyne
    Sam Ballantyne over 8 years
    Now that CI/CD systems are pretty common, you may want to point out the pitfalls of using build scripts to set version #'s with those.
  • Raphael
    Raphael about 7 years
    Things have been renamed for Swift 3.0: it's Bundle.main.object(forInfoDictionaryKey: "...") now.
  • Raphael
    Raphael about 7 years
    Things have been renamed for Swift 3.0: it's Bundle.main.object(forInfoDictionaryKey: "...") now.
  • Raphael
    Raphael about 7 years
    Bundle.main had an empty infoDictionary for me; maybe because I'm doing it from within a framework, not an executable or app? Bundle(for: MyClass.self) contains the expected values.
  • Alex Zavatone
    Alex Zavatone about 4 years
    Warning. The New Build System doesn't copy CFBundleVersion into the app's dictionary. FYI. Tested in Xcode 11.4.
  • Rethunk
    Rethunk over 3 years
    @AlexZavatone, are you still seeing the same problems in XCode 12 with CFBundleVersion not being copied into the dictionary? In XCode 12.4 it's working for me, and with my app project I'm able to retrieve CFBundleShortVersionString successfully. XCode12 is the first version I'm using, so perhaps this is related to the change from CFBundleVersion to CFBundleShortVersionString?
  • Alex Zavatone
    Alex Zavatone over 3 years
    @Rethunk, I'll have to check it out. Thanks for the heads up.