App Store Submission: Redundant Binary Upload

My submission to the app store was rejected due to non-public API usage in one of the declares libraries I was using. I’ve fixed the issue and gone to upload the new build, but I’m getting the following problem:

ERROR ITMS-4238: “Redundant Binary Upload. There already exists a binary upload with build version ‘2.0.0’ for train ‘2.0’” at SoftwareAssets/PreReleaseSoftwareAsset

The remedy for this is that each new build needs a unique build number. This is accomplished in Xojo by enabling Auto-Increment version. However, it looks like when Xojo builds for iOS it will strip the Non Release Version number, causing all of the items to be uploaded with strictly their visible version number (2.0 (2.0.0) for example, instead of 2.0 (45) for non-release version 45).

Is there any way to keep the non-release version number in there so that we can upload multiple builds of the same version without having to artificially advance visible version numbers?

Bump. Same thing happens when an update gets rejected and you need to submit another binary for the same version of an app.

What is everyone else doing when submitting to the app store when something gets rejected on the first try?

Each binary you upload to the App Store needs to have a unique version number. When you build for iOS in Xojo, this comes from the Major, Minor and Bug version numbers. The non-release version number is not used. In addition I use the Short Version to group my releases. So I’m up to version 1.12 of my app, which means my Short Version is set to 1.12 (which matches the next release number for my app in iTunes Connect) and each binary that I upload for my test users is 1.12.1, 1.12.2, etc.

I think they’re looking at the Short Version.
I do this for OS X. I assume it’s the same for iOS Apps.

Insert -> Build Step -> Script

Name is something like ‘SetShortVersion’ and use this code:

  Dim version As String
  version = PropertyValue("App.MajorVersion") + "." + PropertyValue("App.MinorVersion") + "." + PropertyValue("App.BugVersion")
  PropertyValue("App.ShortVersion") = version

I summarised it a few months ago in this thread: https://forum.xojo.com/21559-itunes-connect-build-numbering

Yes, what I’m saying is the non-release version should be used. If I’m submitting version 2.0.1 to the app store and it gets rejected for any reason, I don’t want to then change the app to be 2.0.2 and not match the actual version on the app store.

The non-release version is what should be used in this instance so that all binaries have a unique version number. It would be 2.0.1 (100) and then 2.0.1 (101) etc. This is how it works from Xcode, and how it also works when submitting to the Mac App Store, since the non-release version is included there.

Right now for iOS we’re forced to artificially increment version numbers when it could easily be solved by including the non-release version.

FWIW I agree with you. I’ve got some spare points. If you create a feature request I’ll send some your way. :slight_smile:

Thanks I’ve created it here: <https://xojo.com/issue/41447>

Done.

Hmmm sounds like Major Minor Sub should be landing in CFBundleShortVersion
What I’m not sure about is what Apple expects in CFBundleVersion as the two sounds a heck of a lot alike

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. The first integer represents major revisions to the app, such as revisions that implement new features or major changes. The second integer denotes revisions that implement less prominent features. The third integer represents maintenance releases.
The value for this key differs from the value for CFBundleVersion (page 40), which identifies an iteration (released or unreleased) of the app. This key can be localized by including it in your InfoPlist.strings files.

CFBundleVersion
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.

I believe this is a bug in Xojo.

Let me explain.

In Xojo, we set the following Version info:

Major Version
Minor Version
Bug Version

So we get something like 1.0.4

We can read these in the App object for display into a property. I call mine cAppVersion:

cAppVersion = str(me.MajorVersion) + "." + str(me.MinorVersion) + "." + str(me.BugVersion)

Works perfect.

However, when we upload to MAS, there are two different values that are required, CFBundleShortVersionString and CFBundleVersion.

CFBundleShortVersionString should be exactly like my cAppVersion above. So, it’s a value like 1.0.4

According to Apple, CFBundleVersion can be made up of 3 positive numbers, but it doesn’t have to be.

When uploading to iTunes connect, the Version information is a combination of both values, first CFBundleShortVersionString, and then CFBundleVersion, in parentheses.

If you do some research online, you’ll find the “right” way to handle this is:
CFBundleShortVersionString = something like 1.0.4
CFBundleVersion = a positive number, incremented each time you build and upload your app.

This sort of makes sense according to the way Apple uses the values when you upload your app. The CFBundleShortVersionString is supposed to be the MajorVersion.MinorVersion.BugVersion , and the CFBundleVersion is supposed to count the number of builds you upload. This is useful because there are a lot of situations where you need to reject an uploaded binary and upload another one with the same version number, and Apple will reject it when CFBundleVersion is the same (Tom Iwaniec’s original reason for this post).

So if you make CFBundleShortVersionString 1.0.4 and CFBundleVersion 5, then in iTunes Connect it will appear as 1.0.4 (5)

But here is where it gets seriously annoying, and here is where I believe there has got to be a mistake in Xojo.

If you do all of this the way Apple tells you to do it, incrementing CFBundleVersion per build, and using CFBundleShortVersionString as your MajorVersion.MinorVersion.BugVersion string, then you change the internal values of App.MajorVersion, App.MinorVersion, and App.BugVersion when you change CFBundleVersion!

In other words, in Xojo, App.MajorVersion, App.MinorVersion, and App.BugVersion appear to be pointing to the wrong plist value. They should point to CFBundleShortVersionString but they are (wrongly) pointing to CFBundleVersion

There is one other annoying thing Apple has done here that might help spare someone pain. CFBundleVersion MUST be incremented in each subsequent upload to MAS. You cannot upload CFBundleVersion 5 and then after that upload CFBundleVersion 4. Apple rejects it, and sends you an email telling you it’s wrong and you have to fix it.

*** added the above information to case <https://xojo.com/issue/41447> and attached a project with corresponding applescript showing how changing the plist value for CFBundleVersion results in changed values for App.MajorVersion, App.MinorVersion, and App.BugVersion

I’ve added a test/demo app (OSX) to the case.

As a workaround, you could set App.ShortVersion in your pre-build script to something like this:

PropertyValue(“App.ShortVersion”) = PropertyValue(“App.MajorVersion”) + “.” + PropertyValue(“App.MinorVersion”) + “.” + PropertyValue(“App.BugVersion”) + " (" + PropertyValue(“App.NonReleaseVersion”) + “)”

And then use the App.ShortVersion to display version info in your App.

[quote=233790:@Marco Hof]I’ve added a test/demo app (OSX) to the case.

As a workaround, you could set App.ShortVersion in your pre-build script to something like this:

PropertyValue(“App.ShortVersion”) = PropertyValue(“App.MajorVersion”) + “.” + PropertyValue(“App.MinorVersion”) + “.” + PropertyValue(“App.BugVersion”) + " (" + PropertyValue(“App.NonReleaseVersion”) + “)”

And then use the App.ShortVersion to display version info in your App.[/quote]

Marco I think you might have missed the point of this case. It isn’t about displaying version info within the app. It’s about how the version info is setup in the plist and how that affects the way that the version is used by iTunes Connect.

Hmmm… I don’t think I did.

If you want your version info to display correctly by iTunes connect, you need to change the plist values CFBundleShortVersionString and CFBundleVersion.

Something like this in your post-build script:

  // Get CFBundle and CFBundleShort Version
  Dim CFBundle, CFBundleShort As String
  CFBundleShort = PropertyValue("App.MajorVersion") + "." + PropertyValue("App.MinorVersion") + "." + PropertyValue("App.BugVersion")
  CFBundle = PropertyValue("App.NonReleaseVersion")
  
  // This App
  Dim App As String = CurrentBuildLocation + "/""" + CurrentBuildAppName + ".app"""
  
  // Modify plist
  Call DoShellCommand("/usr/bin/defaults write " + App + "/Contents/Info ""CFBundleVersion""" + " " + CFBundle)
  Call DoShellCommand("/usr/bin/defaults write " + App + "/Contents/Info ""CFBundleShortVersionString""" + " " + CFBundleShort)

However, if you do that, you can’t use App.xxxVersion anymore within your App due to a bug. Aaron filed a bug report, I added an example project in Feedback and showed my workaround for that bug.

My apologies. It seems as if the original thread topic/feedback case has changed. I’m not sure that these are the same problem/solution though but I can see that your reply is to the situation where we find ourselves now. :slight_smile:

No worries. :slight_smile:
Yes, it went a little the other way. I had to read a few times before I noticed the turn.
(I also think it would have been more clear if that feedback case was filed as a new bug report.)

@Aaron [quote]There is one other annoying thing Apple has done here that might help spare someone pain. CFBundleVersion MUST be incremented in each subsequent upload to MAS. You cannot upload CFBundleVersion 5 and then after that upload CFBundleVersion 4. Apple rejects it, and sends you an email telling you it’s wrong and you have to fix it. [/quote]

Yesterday I fell exactly into this trap. When I was ready to make the final build for submission to MAS, I noticed that the non-release version for the app was 228. And I changed it into 28, getting within minutes the above mentioned rejection from Apple. So, after reading this post (thank you, Aaron!), I restored the original 228 and everything got through.

Now my dumb question is: next time I upload to MAS, the non-release number must only increase by one unit (at present, from 228 to 229), or any higher value (ex. 230) is all right?