Which iOS app version/build number(s) MUST be incremented upon App Store release?
Asked Answered
I

10

157

Version/build fields for an iOS app include:

  • "Version" CFBundleShortVersionString (String - iOS, OS X) specifies the release version number of the bundle, which identifies a released iteration of the app. The release version number is a string comprised of three period-separated integers.

  • "Build" CFBundleVersion (String - iOS, OS X) specifies the build version number of the bundle, which identifies an iteration (released or unreleased) of the bundle. The build version number should be a string comprised of three non-negative, period-separated integers with the first integer being greater than zero. The string should only contain numeric (0-9) and period (.) characters. Leading zeros are truncated from each integer and will be ignored (that is, 1.02.3 is equivalent to 1.2.3). This key is not localizable.

  • "iTunes Connect Version Number": version number you specify when creating a new version of the app on iTunes Connect.

My question is:

Which version/build numbers are required to be incremented when a new version of the app is uploaded to iTunes Connect and/or released to the App Store?

Can either "version" CFBundleShortVersionString or "build" CFBundleVersion remain the same between app updates?

Extra points for Apple sources or the exact error messages iTunesConnect displays upon uploading an invalid version/build number.


Android / Google Play note:

The discussion prompting this question is that the public "version" of an Android app in the Google Play Store does not need to be incremented and is in no way validated. The android:versionName can remain the same between releases, upgrade, downgrade, or be any random string rather than something that appears to be a valid "version number".

android:versionName — A string value that represents the release version of the application code, as it should be shown to users.

The value is a string so that you can describe the application version as a <major>.<minor>.<point> string, or as any other type of absolute or relative version identifier.

Difference between versionName and versionNumber in Android

Whereas the android:versionCode is enforced to be an incrementing-on-release integer.


Apple documentation

As noted in the newly accepted answer, Apple has recently published a Technical Note that details their version and build number scheme:

Apple Technical Note TN2420 - Version Numbers and Build Numbers

Improvvisatore answered 14/1, 2014 at 22:16 Comment(1)
A detailed answer with screenshot: https://mcmap.net/q/152754/-what-values-should-i-use-for-cfbundleversion-and-cfbundleshortversionstringInterjection
B
170

Apple Technical Note TN2420, Version Numbers and Build Numbers

Summary:

  • The pair (Version, Build number) must be unique.
    • The sequence is valid: (1.0.1, 12) -> (1.0.1, 13) -> (1.0.2, 13) -> (1.0.2, 14) ...
  • Version (CFBundleShortVersionString) must be in ascending sequential order.
  • Build number (CFBundleVersion) must be in ascending sequential order.

Version Number and Build Number Checklist

Here are some things you can check when submitting a new build to the App Store. Making sure you have your Version Number and Build Number set properly will help you by avoiding having your App automatically rejected for having them improperly configured.

  1. For each new version of your App, you need to invent a new Version Number. This number should be a greater value than the last Version Number that you used. Though you may provide many builds for any particular release of your App, you only need to use one new Version Number for each new release of your App.
  2. You cannot re-use Version Numbers.
  3. For every new build you submit, you will need to invent a new Build Number whose value is greater than the last Build Number you used (for that same version).
  4. You can re-use Build Numbers in different release trains, but you cannot re-use Build Numbers within the same release train. For macOS apps, you cannot re-use build numbers in any release train.

Based on the checklist, the following (Version, Build Number) sequence is valid too.

  • Case: reuse Build Number in different release trains. (NOTE: NOT macOS app)

    (1.0.0, 1) -> (1.0.0, 2) -> ... -> (1.0.0, 11) -> (1.0.1, 1) -> (1.0.1, 2)

Bushcraft answered 24/6, 2016 at 9:23 Comment(13)
I'm confused. One of the conditions is "You cannot re-use Version Numbers," but in the last example, version numbers are staying the same while build numbers are increasing. Am I misinterpreting something?Carlow
@Emil, I think that it's (Version, Build Number) pair cannot be reused.Bushcraft
@EmilParikh Version numbers can be uploaded to Apple multiples times prior to release, each with a unique Build number. But once it has been released, you cannot reused that Version number.Improvvisatore
TN2420 says "Version numbers and build numbers may have up to three components separated by periods" and then provides the following illegal example 1.10000.1.5. However it looks like many apps, including chrome use a version number that contains 4 components (e.g. 68.0.3440.83). I guess this could be explained by the fact that the TN2420 page mentions "Important: This document is no longer being updated." however I haven't been able to find an updated doc that defines the new rules. Anyone else confused?Flamen
@catanman I like this Semantic Version. Let version be composed with (major, minor, patch) manner. And I had used 4 components before, but App store doesn't accept that format with 4 components.Bushcraft
@Bushcraft I use semver as well. It's great. Any idea why chrome is able to submit an app version with 4 components.(e.g. 68.0.3440.83)?Flamen
@catanman, I google and find this. It's 4 digit composed with MAJOR.MINOR.BUILD.PATCH. And iOS separate the BUILD_NUMBER as a solo property. Hope this help you.Bushcraft
@AechoLiu, thank you that helps. I guess the limitation of 3 components that is specified in TN2420 no longer applies. Do you agree?Flamen
I am using 3 components in Version, and 2 components in Build number. Sometimes I will extends Build Number with 3 components. I integrate them in Jenkins script. And our team accept the MAJOR.MINOR.PATCH way to define version number.Bushcraft
with the format MAJOR.MINOR.BUILD.PATCH can a BUILD number be allzero i.e. 0000 ?Rimola
By mistake, submitted two identical Version and Build number packages twice. App Connect increased the Build number of the second submit automatically by 1 by itself. Hence I ended up with 1.3 (50) being 1.3 (50) and the second 1.3 (50) becoming 1.3 (51). I didn't find any documentation, that in this particular case, App Connect increases the build number by itself, hence generating a mismatch between the entered Xcode build and the App Connect build. Is this a known/documented behavior?Impignorate
@Bushcraft continuing your example for iOS apps, does this mean (before release to App Store) you can upload this "out or order" seq as well: (1.0.0, 1) -> (1.0.0, 2) -> ... -> (1.0.0, 11) -> (1.0.1, 1) -> (1.0.1, 2) -> (1.0.0, 3) -> (1.0.1, 3) flipping beetween the patch (3rd) component back and forth like that, seeming "out of order"? Because I think i've seen that done as well before with other apps uploading for TF before app store submission but i never thoguht you could do thatXerophagy
@Xerophagy In my experience, it depends on the released Version on app store. If the 1.0.0 version released in the app store, then only > 1.0.0 version can be uploaded to apple store & TestFlight. My case: In apple store, the released version is 1.0.0. And, we are developing the 1.1.0 for next release version, but find a critical bug and release a patch version 1.0.1 to apple store. So, we will push 1.1.0 and 1.0.1 to Apple store, one for developing and testing, and another for patching critical bug.Bushcraft
A
39

The CFBundleShortVersionString should match the version number you give iTunes Connect. It is also the version number that appears when the user looks at your App in the App Store.

The version number is shown in the store and that version should match the version number you enter later in iTunes Connect.

Source

The CFBundleVersion is not displayed in the App Store, but is used by the iTunes to determine when your App has been updated.

If you update the build string, as described in “Setting the Version Number and Build String,” iTunes recognizes that the build string changed and properly syncs the new iOS App Store Package to test devices.

Source

Answering your questions more specifically...

Which version/build numbers are required to be incremented when a new version of the app is uploaded to the app store?

Both. One is displayed in the App Store, the other is used by iTunes to update the App.

Can either CFBundleShortVersionString or CFBundleVersion remain the same between app updates?

No. (Meta question, what would the use case be here? If you've edited the payload in any way, the build will be different, and the user will want to know about it). If you try, you'll see error messages like below:

Error messages

Or are they compared to the previous respective number to ensure that a numerically greater number is uploaded with the new version of the app?

Yes. Using the semver.org standard.

Are the CFBundleShortVersionString and CFBundleVersion numbers in any way compared to each other?

No.

Aeromedical answered 14/1, 2014 at 23:3 Comment(6)
Right, I know how the two numbers are used. The question is: are both of them required to be incremented when releasing a new version of the app?Improvvisatore
Yes, if you try to push an App into the App Store without updating both, you will see an error message e.g. #19368393Aeromedical
Thanks, great edit. Especially for that link. The organizer's validator is showing "must contain a higher version" errors for both CFBundleVersion and CFBundleShortVersionString.Improvvisatore
+1 for SemVer link... Given a version number MAJOR.MINOR.PATCH, increment the: MAJOR version when you make incompatible API changes, MINOR version when you add functionality in a backwards-compatible manner, and PATCH version when you make backwards-compatible bug fixes.Saluki
Regarding this: what would the use case be here? If you've edited the payload in any way, the build will be different, and the user will want to know about it. My use case is that my app was successful reviewed by Apple, but never released before in the App Store. I found an error and I want to bugfix it - without changing CFBundleShortVersionString. Is this possible? I want to reject my own app.Caparison
"The CFBundleShortVersionString should match the version number you give iTunes Connect. It is also the version number that appears when the user looks at your App in the App Store." I think neither of these statements is true. You can use whatever you like for it, so long as it is increasing and unique, it's unrelated to the version number in App Store Connect. And it does not appear anywhere in iOS or the app store, unless you manually make it so.Engelhardt
S
34

CFBundleShortVersionString is the public "name" of the version (example: "2.5", or "3.8.1"). You must increase it at each release.

CFBundleVersion is the private build number. It is not seen on the AppStore. You must increase it at each upload. It means that if you ever reject a binary before it goes online, and you want to upload a new binary, it will have the same CFBundleShortVersionString but must have a higher CFBundleVersion (example: public "2.5", private "2.5", and then binary reject, and re-upload private "2.5.1")

Edit on Nov 16, 2016:

/!\ The CFBundleVersion property is also used (along with CFBundleName) in the User-Agent header sent by NSURLConnection in your code.

Example: if CFBundleName is MyApp and CFBundleVersion is 2.21, then any programmatic HTTP query sent directly by your code using NSURLConnection will embed the header:

User-Agent: MyApp/2.21 CFNetwork/... Darwin/...

(This does not apply to requests issued automatically by UIWebView).

Site answered 17/12, 2014 at 9:10 Comment(4)
Great distinction between requirements for upload/release.Improvvisatore
@gabriel, I've tried to set the build number to X.X-rc2 but the Organizer validator doesn't allow me to set anything different from X.Y.Z where X,Y and Z are integer :S . It would be great to have a -rc2 build number, have you ever been able to submit one release with it?Guidotti
@nestor You're right, I was wrong. Only numbers are allowed. Let me edit my answer.Site
@gabriel, I use a script to parse X.X-rc2 to X.X.2, for CI system to generate the buildNumber for uploading to iTunesConnect.Bushcraft
W
6

CFBundleVersion and CFBundleShortVersionString must be greater than the app's last version number. It's a good practice to keep them same. You should find them in your -info.plist.

When you try to validate the app in organizer it will throw an error if either of them has not been incremented. Happened to me last night.

Wakerobin answered 14/1, 2014 at 22:56 Comment(6)
I mentioned both of those keys in my question. Is your answer here that both of those values must be incremented? Can you better support your answer?Improvvisatore
Yes both needs to be incremented. Last night when I tried to submit before increment them, it complained for both the keys.Wakerobin
Thanks for the additional info. You should edit your answer to add your experience when uploading a build.Improvvisatore
"It's a good practice to keep them same" - this isn't necessarily true. If you have testers working on your App, you might like to increment your build number as changes are applied, but keep your version number the same. Using continuous integration, you can have it update your build number for you before deploying to testers, for example.Aeromedical
@Aeromedical you're right, makes sense. Thanks for pointing out the use case. I was only thinking in terms of a single developer/tester environment.Wakerobin
It may be good practice to keep them the same, but if you do, and if you use Apple's TestFlight, you'll find that each build will require a beta review before you can release it for External beta testing. That review is much quicker than App Store review, but still can take up to a day or so. Also, there is a limit of two beta reviews per day which can be a major bottleneck.Apish
I
5

Both CFBundleVersion and CFBundleShortVersionString MUST be incremented when releasing a new version to the App Store.

Additionally, one of the strings must must match the version specified in iTunes Connect.

Xcode Organizer Validator error: must increment the version number.

This question includes the above screenshot of the Xcode Organizer's Validator refusing to validate the app when the CFBundleVersion and CFBundleShortVersionString have not been incremented.

  • This bundle is invalid. The value for key CFBundleVersion [1.0] in the Info.plist file must contain a higher version than that of the previously uploaded version [1.134].

  • This bundle is invalid. The value for key CFBundleShortVersionString [1.0] in the Info.plist file must contain a higher version than that of the previously uploaded version [1.134].

The validator also throws an error proving that one of the strings must match the version of the app created on iTunes Connect.

  • Version Mismatch. Neither CFBundleVersion ['1.0'] nor CFBundleShortVersionString ['1.0'] in the Info.plist match the version of the app set in iTunes Connect ['1.4'].
Improvvisatore answered 14/1, 2014 at 23:31 Comment(0)
T
5

The current Apple Technical Note TN2420, Version Numbers and Build Numbers says (my bolding):

  1. For iOS apps you can re-use build numbers in different release trains, but you cannot re-use build numbers within the same release train. For macOS apps, you cannot re-use build numbers in any release train.

Unfortunately, this means you can't reuse a build number that tracks to the release train number on iOS when you're trying to release the same build on Mac Catalyst.

In my case, for example, due to some earlier issues, I ended up releasing 1.0.2(4) as a Mac Catalyst app that corresponded to 1.0.2(1) on iOS. Now when trying to release 1.0.3(1) on both, the app fails verification on MacOS because of the build number, while it passes verification on iOS.

I guess now that I am releasing the same app on both iOS and MacOS routinely, I will adopt build numbers that correspond to the date, like 20200111 and increment with a decimal point if I need to change the build number within a given release.

Tessitura answered 11/1, 2020 at 18:59 Comment(0)
J
4

I can confirm, having just tried it both ways, that a sequence of version and build numbers like...

1.0.0 (1)
1.0.1 (1)
1.0.2 (1)

...will be accepted for iOS apps, but for Mac (Catalyst) apps it returns this error:

ERROR ITMS-90061: "This bundle is invalid. The value for key CFBundleVersion [1] in the Info.plist file must contain a higher version than that of the previously uploaded version [2]."

The Mac version and build numbers would need to go like...

1.0.0 (1)
1.0.1 (2)
1.0.2 (3)

For iOS, I used to enter build numbers as the version number plus a fourth digit, like...

1.0.0 (1.0.0.1)
1.0.1 (1.0.1.1)
1.0.2 (1.0.2.1)

...but that isn't allowed for Mac apps, either. When I tried submitting my first Mac (Catalyst) app, Apple would only accept a build number with three or fewer digits:

ERROR ITMS-9000: "This bundle is invalid. The value for key CFBundleVersion [1.0.0.1] in the Info.plist file must be a period separated list of at most three non-negative integers."

So I changed to a single number that increments for every build and continues incrementing across version numbers.

Jerilynjeritah answered 11/3, 2020 at 16:12 Comment(1)
Do you have any of the error messages it gave you? Please quote them if so!Improvvisatore
I
2

I'm preparing to release a new Mac App Store app. Using CalVer formatting of YEAR.release (build).

I uploaded several builds: 2020.0 (1), 2020.0 (2), etc. I finally submitted 2020.0 (8) for App Store Review. That passed review and is in the state Pending Developer Release.

I wanted to fix a few things before release, so I added a new build to the same release train: 2020.0 (9).

That results in the error:

App Store Connect Operation Error

ERROR ITMS-90062: "This bundle is invalid. The value for key CFBundleShortVersionString [2020.0] in the Info.plist file must contain a higher version than that of the previously approved version [2020.0]. Please find more information about CFBundleShortVersionString at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring"

which is annoying as my 2020.0 version was never actually released. From the accepted answer of this question I was under the impression that until the app was available on the App Store you could continue to release new builds with the same version.

The solution seems to be that a "release train" (Same Version + New Build) cannot be updated if the app state is Pending Developer Release. Either release your existing build and then increase the version, or Cancel this Release in App Store Connect to allow further uploads for this release train.

Improvvisatore answered 30/3, 2020 at 5:44 Comment(1)
If it helps with context, I worked on an app circa 2015, and I think we used the same build strategy you did, and it was allowed. When I was managing another app in about 2018, I got the errors you did, so I think the rules had changed to what you've described.Union
I
1

You need to increment both.

When uploading a new version, you will need to create a new version on the iTunes Connect, which automatically will be higher than the previous releases. This version on the iTunes Connect will be expecting a binary with the same version number, thus CFBundleShortVersionString needs to be incremented.

If you update the version but forget to increment the CFBundleVersion, you will encounter an error during the upload. See pkamb's answer and screenshot.

For details on CFBundleShortVersionString and CFBundleVersion, please see: https://mcmap.net/q/152754/-what-values-should-i-use-for-cfbundleversion-and-cfbundleshortversionstring

Interjection answered 18/11, 2015 at 11:57 Comment(0)
E
-4

AFAIK, off the top of my head, you only need to increment the build number CFBundleVersion. Incrementing the short version string is not necessarily needed, though you probably should increment it, as it does tell the user that the app is new. Apple does say that numbering should follow traditional software versioning conventions, however, and iTunes Connect may complain if you try to re-upload an already existing version.

Long story short, it may work, but probably not.

Evaporite answered 14/1, 2014 at 22:22 Comment(1)
Looking for authoritative answers on which keys must be incremented. If CFBundleShortVersionString is not required to be incremented, the "same" user-facing version can then be uploaded to the App Store multiple times?Improvvisatore

© 2022 - 2024 — McMap. All rights reserved.