Changing CURRENT_PROJECT_VERSION modifies values within your project's project. pbxproj file and if you are running a distributed team, this will cause merge conflicts if the other half of the team tries to update and while they were asleep, you updated this internal value.
CFBundleShortVersionString gives you the version of your app. It's typically incremented each time you publish your app to the App Store. This is the version that is visible on the "Version" section for the App Store page of your application.
CFBundleVersion gives you the build number which is used for development and testing, namely "technical" purposes. The end user is rarely interested in the build number but during the development you may need to know what's being developed and fixed on each build. This is typically incremented on each iteration of internal release. And you can use continuous integration tools like Jenkins to auto-increment the build number on each build.
The two numbers do not depend on each other but it is a good idea to keep them parallel to avoid confusion. Keep in mind that once your app has passed the App Store review you need to increment the build number like Phil and likeTheSky have stated, regardless of whether you publish it or not.
Use case: Let's say, you have a well-tested build, ready for submission. It's version number is 1.0.0 and build number is 1.0.0.32. Once you submit your app, you need to update the version as 1.0.1 and build number as 1.0.1.0.
Think of it this way: The "short version" (CFBundleShortVersionString
) is the public version number. The "version" (CFBundleVersion
) is more of an internal version number that could change far more frequently than the public "short version". Personally I use the same for both but many people update the "version" on every build. Either way you typically update the "short version" when you release to Apple. How often you update the "version" is up to you and your needs.
The answer by rmaddy is correct. I'll add two more thoughts.
Be aware of the third version number, specified on the iTunesConnect web site as part of your app's definition. If that number is different than the two in Xcode, Apple gives you a warning. You can ignore the warning, as it is not a show-stopper (not an "error").
Also, you need not use three numbers with punctuation. That may may sense for some apps, where traditionally changes in the first number indicated some kind of dramatic change usually affecting compatibility.
For other apps you might want to use simply a date-time value in ISO 8601 standard format style (YYYYMMDDHHMM). For example, 201606070620
. That order of year-month-date-hour-minute renders an ever-increasing number, always the same length due to padding zero, that when sorted alphabetically is also chronological.
I have successfully used this style of version numbers on a shipping iOS app working in iOS 7, 8, & 9.
You can even automate the generation of this value. In your project’s Target
> Build Phases
> Run Script
panel:
Shell
field: /bin/sh
Show environment variables in build log
checkbox.Run script only when installing
checkbox.Every time you do a build the current date-time in UTC time zone is captured. The -u
flag in the script makes use of UTC rather than your current default time zone. Generally best for programmers and sysadmins to be using and thinking in UTC rather than local time zones.
#!/bin/bash
buildNumber=$(date -u "+%Y%m%d%H%M")
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $buildNumber" "$INFOPLIST_FILE" # Version number
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE" # Build number
echo "DateTime for app version number: $buildNumber"
Or do a hybrid, with a conventional 1.2.3
for the Version number and a date-time as the Build number. To do the hybrid, simply comment-out the CFBundleShortVersionString
line with a #
in front.
The scheme most sensible to me is to use the version number (ie. CFBundleShortVersionString
) for the actual version number, and then use the build number (ie. CFBundleVersion
) to represent the submission to the App Store. So unless there are any problems and hence re-submits, this number is always 1. For a new release, I reset to 1 if the previous had issues in TestFlight testing or in review.
Build numbers provide a way to name each of the submissions you provide for a particular release. As described in the definitions above, the collection of all of the builds that you provide for a particular version of your app is called that version's 'release train'. For iOS apps, build numbers must be unique within each release train, but they do not need to be unique across different release trains [my emphasis]. That is to say, for iOS Apps you can use the same build numbers again in different release trains if you want to.
From Technical Note TN2420: Version Numbers and Build Numbers.
I use CFBundleVersion to indicate internal build for CFBundleShortVersionString. I use test flight to submit builds for my testers so the difference between them has been extremely useful.
Apple documents says CFBundleVersion "should be a string comprised of 3 non-negative, period-separated integers" But actually it can be MORE THAN 3 parts(as the above answer shows). I use that to indicate my development build, say my CFBundleShortVersionString is 1.0.0, I can use 1.0.0.11 for CFBundleVersion to indicate that is my 11th build for release 1.0.0
Each CFBundleVersion submitted to app store should be bigger than before or you will get ERROR ITMS-90478: "Invalid Version. The build with the version “xxx” can’t be imported because a later version has been closed for new build submissions. Choose a different version number."
CFBundleShortVersionString can only have 3 parts or you will get ERROR ITMS-90060:The value for key CFBundleShortVersionString 'xxx' in the Info.plist file must be a period-separated list of at most three non-negative integers."
The 3rd number that Basil Bourque mentioned, i.e. the version number shows on iTunesConnect is where things may get complicated.
I use a different iTunesConnect number than CFBundleShortVersionString because when I first submitted my app to app store we already have many rounds of internal releases. So I used 1.0 for iTunesConnect number and 5.x for CFBundleShortVersionString. In the next release to app store I provided a function to check if there is a newer version in the app store and realized I had trouble now because I can only get iTunesConnect number (using http://itunes.apple.com/lookup?bundleId=
) so I need to do some calculation to before compare it with CFBundleShortVersionString number.
I tried to fix that by using iTunesConnect number as my CFBundleShortVersionString, but got the error, ERROR ITMS-90062: "This bundle is invalid. The value for key CFBundleShortVersionString [x.x.x] in the Info.plist file must contain a higher version than that of the previously approved version [x.x.x]."
So I will suggest always make them the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With