135

Is there a way to programmatically get the build version of my app? I need to be able to detect when the user has updated the app through the AppStore, in order to execute some code for adjustments

rmaddy
  • 314,917
  • 42
  • 532
  • 579
jcardenete
  • 1,646
  • 3
  • 13
  • 16
  • See also http://stackoverflow.com/questions/7608632/how-do-i-get-the-current-version-of-my-ios-project-in-code – Alex Nolasco Oct 01 '14 at 17:47
  • Also see http://stackoverflow.com/questions/458632/how-can-my-iphone-app-detect-its-own-version-number/18669222#18669222 – rodamn Oct 02 '15 at 19:16

7 Answers7

302

The value you set in the Xcode target summary's "Version" field is in here:

Swift 3

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

ObjC

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

Swift 2

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

and the "Build":

Swift 3

let build = Bundle.main.infoDictionary?[kCFBundleVersionKey as String] as? String

ObjC

NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey];

Swift 2

let build = NSBundle.mainBundle().infoDictionary?[kCFBundleVersionKey as String] as! String
e1985
  • 6,239
  • 1
  • 24
  • 39
  • 5
    Using the string literal and not the constant isn't future-proof; see Anupdas's answer for the constant keys. – Aaron Brager Jun 03 '13 at 01:40
  • 9
    You are right for the @"CFBundleVersion" - I have edited my answer. However for @"CFBundleShortVersionString" there is no constant AFAIK. – e1985 Jun 03 '13 at 02:29
  • For Swift, `NSBundle.mainBundle()` is now `Bundle.main` – Todd Nov 25 '16 at 18:20
85

You can try using the infoDictionary

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

NSString *version = infoDictionary[@"CFBundleShortVersionString"];
NSString *build = infoDictionary[(NSString*)kCFBundleVersionKey];
NSString *bundleName = infoDictionary[(NSString *)kCFBundleNameKey]; 
Anupdas
  • 10,211
  • 2
  • 35
  • 60
14

When using MFMailComposeViewController for a "Contact Us" button, I use this code to get a formatted HTML on the e-mail from the user. It gives me all the info that I need to start helping solving any issue:

#import <sys/utsname.h> // Don't forget to import that somewhere //

struct utsname systemInfo;
uname(&systemInfo);

NSDateFormatter *formatter = [[NSDateFormatter alloc]  init];
NSDate  *date = [NSDate date];
[formatter setDateFormat:@"MM/dd/yyyy 'at' hh:mm a"];
NSString *dateString = [formatter stringFromDate:date];

CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width - 65.0;

NSString *comments = NSLocalizedString(@"Please write your comments below:", nil);
NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
NSString *deviceModel = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
NSString *iOSVersion = [[UIDevice currentDevice] systemVersion];

NSString *emailBody = [NSString stringWithFormat:@"<!DOCTYPE html><html><style> .div {background-color: lightgrey; width: %fpx; padding: 10px; border: 5px solid navy; margin: 2px;}</style><body><div class='div'><p><b>App:</b> %@</p><b><p>Device:</b> %@</p><b><p>iOS Version:</b> %@</p><b><p><p>App Version and Build:</b> %@ (%@)</p><b><p>Date:</b> %@</p> </p></div><font color='red'><b>%@</b></font><br><br></body></html>",screenWidth,appName,deviceModel,iOSVersion,version,build,dateString,comments];

[self setMessageBody:emailBody isHTML:YES];

This is the result when getting the message:

enter image description here

Idan
  • 9,880
  • 10
  • 47
  • 76
neowinston
  • 7,584
  • 10
  • 52
  • 83
4

Swift version for both separately:

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

Esqarrouth
  • 38,543
  • 21
  • 161
  • 168
  • You should make it clear that you own that repo. You don't want to come off as a spammer. – JAL Feb 26 '16 at 17:01
3

1)For getting App version you have to use a:

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

2)For getting Build version you have to use a:

NSString *buildVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
S. S
  • 169
  • 3
  • 16
Vaibhav Shiledar
  • 939
  • 8
  • 15
2

Details

  • Xcode Version 10.3 (10G8), Swift 5

Solution

class Info {
    static let dictionary = Bundle.main.infoDictionary ?? [:]
    enum Value {
        case build, version
    }
}

extension Info.Value {

    var key: String {
        switch self {
            case .build: return kCFBundleVersionKey as String
            case .version: return kCFBundleInfoDictionaryVersionKey as String
        }
    }

    var string: String? { return Info.dictionary[key] as? String }
}

Usage

if let value = Info.Value.version.string { print("Version: \(value)") }
if let value = Info.Value.build.string { print("Build: \(value)") }

Result

Project settings

enter image description here

Vasily Bodnarchuk
  • 24,482
  • 9
  • 132
  • 127
1

I have written this open source project for precisely this purpose. My project posts notifications when significant events occur, such as when a user opens the app for the first time, or opens the app after upgrading (complete with information on which version the user upgraded from). The source is straightforward and should be easy to understand. Let me know if you have any questions/requests.

I have also recently written a blog post about it.

Stunner
  • 12,025
  • 12
  • 86
  • 145