256

I'm writing an iPhone app. It's already been published, but I would like to add a feature where its version number is displayed.

I'd rather not have to do this manually with each version I release...

Is there a way in objective-C to find out what the version is of my app?

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
  • 1
    This question has already been answered here http://stackoverflow.com/a/16888788/2890157. – Akshat Singhal Oct 22 '13 at 05:28
  • 1
    .. the linked question is 4 year later, so the real issue here is that cmos never *accepted* an answer. Regardless, the linked question's answers are useful, as are the answers here. On both threads, look beyond first answer - sometimes there is more up-to-date info on a later answer. – ToolmakerSteve Jan 30 '17 at 19:40

16 Answers16

224

As I describe here, I use a script to rewrite a header file with my current Subversion revision number. That revision number is stored in the kRevisionNumber constant. I can then access the version and revision number using something similar to the following:

[NSString stringWithFormat:@"Version %@ (%@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"], kRevisionNumber]

which will create a string of the format "Version 1.0 (51)".

Community
  • 1
  • 1
Brad Larson
  • 170,088
  • 45
  • 397
  • 571
  • 154
    That returned my build version so I used this one. [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] – jspooner May 19 '12 at 02:08
  • 6
    CFBundleVersion is incorrect, because Xcode erroneously populates that plist entry with the build number and not the version number. jspooner is correct. – Oscar Jan 30 '13 at 20:34
  • 4
    See http://stackoverflow.com/questions/6851660/version-vs-build-in-xcode-4 for a great explanation of Version vs Build numbers. Confirms that `CFBundleShortVersionString` what you'd normally want for 'version' and `CFBundleVersion` for Build number. – Rory Feb 02 '13 at 18:15
  • 3
    kRevisionNumber doen't seem to work for me. To get the output specified I did this (using @jspooner 's fix): `[NSString stringWithFormat:@"Version: %@ (%@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]` – Adam Apr 30 '15 at 18:19
151

Building on Brad Larson's answer, if you have major and minor version info stored in the info plist (as I did on a particular project), this worked well for me:

- (NSString *)appNameAndVersionNumberDisplayString {
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
    NSString *appDisplayName = [infoDictionary objectForKey:@"CFBundleDisplayName"];
    NSString *majorVersion = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
    NSString *minorVersion = [infoDictionary objectForKey:@"CFBundleVersion"];

    return [NSString stringWithFormat:@"%@, Version %@ (%@)", 
                appDisplayName, majorVersion, minorVersion];
}

Now revving a minor version manually can be a pain, and so using a source repository revision number trick is ideal. If you've not tied that in (as I hadn't), the above snippet can be useful. It also pulls out the app's display name.

idStar
  • 10,674
  • 9
  • 54
  • 57
60

Swift version for both separately:

Swift 3

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

Swift 2

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

Its included in this repo, check it out:

https://github.com/goktugyil/EZSwiftExtensions

clozach
  • 5,118
  • 5
  • 41
  • 54
Esqarrouth
  • 38,543
  • 21
  • 161
  • 168
43

This is what I did in my application

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

Hopefully this simple answer will help somebody...

Arkady
  • 3,196
  • 24
  • 19
31

You can specify the CFBundleShortVersionString string in your plist.info and read that programmatically using the provided API.

CharlesB
  • 86,532
  • 28
  • 194
  • 218
Jasper Bekkers
  • 6,711
  • 32
  • 46
30

There are two things - build version and app version.

  1. To get App version:

    NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    
  2. To get Build version:

    NSString *buildVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
    
Pang
  • 9,564
  • 146
  • 81
  • 122
Shaik Riyaz
  • 11,204
  • 7
  • 53
  • 70
  • Is there any difference between these two? They both return the same for me. – jjnevis Mar 19 '15 at 13:21
  • yes , may be your build number and app version are same in settings . – Shaik Riyaz Mar 19 '15 at 13:29
  • Okay, I only have one setting in my RAKEFILE - app.version (I'm using RubyMotion). I guess either will do for my needs. Thanks – jjnevis Mar 19 '15 at 16:40
  • Thanks, mate. Worked smoothly. – Felipe Apr 15 '15 at 17:07
  • 1
    FYI It's preferable to use `objectForInfoDictionaryKey:` instead of `infoDictionary] objectForKey:` because the former returns the localised value (if there is one). Probably won't make a difference here though ;) – deanWombourne Jun 15 '15 at 10:00
18

A succinct way to obtain a version string in X.Y.Z format is:

[NSBundle mainBundle].infoDictionary[@"CFBundleVersion"]

Or, for just X.Y:

[NSBundle mainBundle].infoDictionary[@"CFBundleShortVersionString"]

Both of these snippets returns strings that you would assign to your label object's text property, e.g.

myLabel.text = [NSBundle mainBundle].infoDictionary[@"CFBundleVersion"];
rodamn
  • 2,191
  • 19
  • 24
17
// Syncs with App Store and Xcode Project Settings Input
NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
John Erck
  • 9,478
  • 8
  • 61
  • 71
7

You can try using dictionary as:-

NSDictionary *infoDictionary = [[NSBundle mainBundle]infoDictionary];

NSString *buildVersion = infoDictionary[(NSString*)kCFBundleVersionKey];
NSString *bundleName = infoDictionary[(NSString *)kCFBundleNameKey]
Xavi López
  • 27,550
  • 11
  • 97
  • 161
Abhishek Verma
  • 137
  • 1
  • 6
6

Swift 5:

There are two things - App version and build version

  • To get App version:

     if let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
          // present appVersion
    }
    
  • To get Build version:

     if let buildVersion = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
          // present buildVersion
     }
    

Thanks @Brad Larson♦ a lot

dengST30
  • 3,643
  • 24
  • 25
4

You can use the infoDictionary which gets the version details from info.plist of you app. This code works for swift 3. Just call this method and display the version in any preferred UI element.

Swift-3  

func getVersion() -> String {
    let dictionary = Bundle.main.infoDictionary!
    let version = dictionary["CFBundleShortVersionString"] as! String
    let build = dictionary["CFBundleVersion"] as! String
    return "v\(version).\(build)"
}
rajat chauhan
  • 178
  • 1
  • 8
4

Read the info.plist file of your app and get the value for key CFBundleShortVersionString. Reading info.plist will give you an NSDictionary object

lostInTransit
  • 70,519
  • 61
  • 198
  • 274
1

If you need a combination of both version and build num, here's a short way using Swift 3:

let appVersion = Bundle.main.infoDictionary!["CFBundleShortVersionString"]!
let buildNum = Bundle.main.infoDictionary!["CFBundleVersion"]!
let versionInfo = "\(appVersion) (build \(buildNum))"
// versionInfo is now something like "2.3.0 (build 17)"

Add an as! String to the end of either the appVersion or buildNum line to get only that portion as a String object. No need for that though if you're looking for the full versionInfo.

I hope this helps!

Jeehut
  • 20,202
  • 8
  • 59
  • 80
1
func getAppVersion() -> String {
    let dictionary = Bundle.main.infoDictionary!
    let versionValue = dictionary["CFBundleShortVersionString"] ?? "0"
    let buildValue = dictionary["CFBundleVersion"] ?? "0"
    return "\(versionValue) (build \(buildValue))"
}

Based on @rajat chauhan answer without forced cast to String.

apex39
  • 603
  • 1
  • 6
  • 20
0

This is a good thing to handle with a revision control system. That way when you get a bug report from a user, you can check out that revision of code and (hopefully) reproduce the bug running the exact same code as the user.

The idea is that every time you do a build, you will run a script that gets the current revision number of your code and updates a file within your project (usually with some form of token replacement). You can then write an error handling routine that always includes the revision number in the error output, or you can display it on an "About" page.

D'Arcy Rittich
  • 167,292
  • 40
  • 290
  • 283
0

You can try this method:

NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
BatyrCan
  • 6,773
  • 2
  • 14
  • 23