Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-17993] iOS: Split CFBundleVersion and CFBundleShortVersionString

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2015-07-06T21:44:44.000+0000
Affected Version/sn/a
Fix Version/sRelease 4.1.0
ComponentsiOS, Tooling
Labelsmerge-4.0.0
ReporterStephen Feather
AssigneeFokke Zandbergen
Created2014-11-09T13:12:33.000+0000
Updated2015-07-06T21:44:48.000+0000

Description

Early on the growth of iOS development the use of CFBundleVersion and CFBundleShortVersionString interchangeably was a tolerable behavior. However, these are two unique keys. The problem with using them interchangeably was originally raised when the Testflight ad-hoc distribution service became available. With Apple now having acquired the Testflight platform and incorporating it into their iTunes Connect platform, it is time to separate these two keys and to use them properly. This will require changes to the CLI tooling and the exposing of these to the tiapp.xml editor in Studio. Parity: TISTUD-5088 Android: Expose versionCode and versionName in TiApp Editor View Reference: https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html {quote} CFBundleShortVersionString 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, which identifies an iteration (released or unreleased) of the app. This key can be localized by including it in your InfoPlist.strings files. {quote} {quote} 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. {quote}

Comments

  1. Stephen Feather 2014-11-09

    Currently, if we place the following in the tiapp.xml, it is overwritten by tooling to match the value of
    <version>1.0.1</version>
       <ios>
         <plist>
           <dict>
             <key>CFBundleShortVersionString</key>
             <string>12.0</string>
       
    Generated info.plist:
       <key>CFBundleVersion</key>
       <string>1.0.1</string>
       <key>CFBundleShortVersionString</key>
       <string>1.0.1</string>
       
    If we try to force
    <key>CFBundleVersion</key>
    it also is overwritten.
  2. Chris Barber 2014-11-09

    Just out of curiosity, how does Xcode expose these two versions? I presume that one of them has its own field on the project properties screen. Does the other version have its own field too or do you have to edit the Info.plist directly?
  3. Stephen Feather 2014-11-10

    !http://content.screencast.com/users/Stephen_Feather/folders/Jing/media/2ac2fd9e-eba3-4ff3-aff8-2ae554b5a8ed/00000676.png!
  4. Timan Rebel 2014-11-10

    [~fokke] wrote a great piece on how to handle both iOS and Android versioning http://www.tidev.io/2014/10/29/versioning-builds-and-releases/
  5. Stephen Feather 2014-11-10

    I'll be polite, but actually, no he didn't. His approach to android versioning is nonstandard as your builds do not increment by 1, but by large numbers. Good luck managing that in the play store.
       grunt.registerTask('tiapp', function() {
               var tiapp = require('tiapp.xml').load();
               var versions = tiapp.version.split('.');
               //TODO: if 3rd number reaches 999, reset to 1 and increment 2nd number
               versions[2] = parseInt(versions[2]) + 1;
               tiapp.version = versions.join('.');
        
               var androids = tiapp.doc.documentElement.getElementsByTagName('android');
        
               if (androids.length === 1) {
                   var manifests = androids.item(0).getElementsByTagName('manifest');
        
                   if (manifests.length === 1) {
                       var manifest = manifests.item(0);
                       var versionCode = parseInt(manifest.getAttribute('android:versionCode')) + 1;
                       grunt.log.writeln(versionCode);
                       manifest.setAttribute('android:versionName', versions.slice(0, 3).join('.'));
                       manifest.setAttribute('android:versionCode', versionCode);
                   }
               }
        
               tiapp.write();
        
               grunt.log.writeln(require('util').format('Bumped version to: %s', tiapp.version));
           });
       
    the above fits more inline with what Apple and Google expect (how do I know what apple expects? I look at what their own native tool agvtool does) The problem is that Apple expects 2 values (much as Google does) and ATM the Appc tooling does not allow for this, thus the ticket. AVGTool Question: https://developer.apple.com/library/ios/qa/qa1827/_index.html
  6. Chris Barber 2014-11-10

    [~sfeather] Rad, thanks for the pic. That's what I needed. :)
  7. Fokke Zandbergen 2014-11-27

    I agree [~sfeather] And while I was revising my versioning, I did a PR to enable custom CFBundleVersion and CFBundleShortVersionString: https://github.com/appcelerator/titanium_mobile/pull/6408
  8. Tim Poulsen 2014-12-01

    Dated, but related is https://github.com/appcelerator/titanium_mobile/pull/4932
  9. Simen Sol 2015-01-26

    From testflightapp.com: «The services offered at TestFlightapp.com will shutdown on 2/26/2015». So, splitting CFBundleVersion and CFBundleShortVersionString becomes critical after 2/26/2015.
  10. Stephen Feather 2015-02-07

    Notice that the CFBundleShortVersionString remains as '1.0' while the CFBundleVersion has been changed, allowing for a new binary to be uploaded without changing the app version. !http://content.screencast.com/users/Stephen_Feather/folders/Jing/media/5de97002-6fb9-4aa1-b5e8-157b2028f3ab/00000863.png!
  11. Shannon Hicks 2015-03-11

    Seems that TIMOB-3107 is a duplicate of this issue, too.
  12. Daniel Nichita 2015-03-26

    Ran headlong into this problem as I was trying to submit multiple builds of the same app version to Apple for TestFlight testing. iTunesConnect doesn't accept ipas with duplicate build numbers and since Titanium sets CFBundleVersion and CFBundleShortVersionString equal to each other based on version in tiapp.xml, subsequent submissions of an app of the same version fail to pass validation. The workaround is to open the project file in Xcode, increment the build number, regenerate ipa in Xcode, and resubmit via app loader or directly from organizer, doable, but kind of a pain. @Fokke Zandbergen: Many thanks for addressing this, but is there any chance this could be moved to an earlier sdk update before 4.1.0? I'm sure everyone is running into this problem with Apple's new TestFlight setup.
  13. nicolomonili 2015-04-23

    There is no way , now with SDK 3.5.1, to manage CFBundleVersion and CFBundleShortVersionString ?
  14. Fokke Zandbergen 2015-04-23

    Unfortunately there is not, unless you cherry pick the PR: https://github.com/appcelerator/titanium_mobile/pull/6408 Another alternative is to use an major.minor.patch.build version. Titanium will then use major.minor.patch for CFBundleShortVersionString and major.minor.patch.build for CFBundleVersion. Not ideal, since it does not allow you to have major or major.minor for CFBundleShortVersionString, but at least you get unique builds.
  15. nicolomonili 2015-04-27

    So i hope that the version 4.1.0 comes out soon. This feature is essential for anyone who uses testflight
  16. Hans Knöchel 2015-04-30

    @nicolomonili: 4.0 is still in RC so you might have to wait i bit longer. For TestFlight, simply add another integer, e.g.: 1.2.0.1, 1.2.0.2, ... which works perfect.
  17. Jason Kneen 2015-05-02

    Any update on this? It's a blocker for doing any WatchKit / Extension deployment to device.
  18. Stephen Feather 2015-05-02

    My concern is that the PR adds functionality not requested in the ticket and tickets do not exist for the additional functionality.
  19. Adam 2015-05-03

    Paperwork over progress? If it matters that much, can we not just change the original ticket to match? This is a great addition that is in high demand at the moment.
  20. Stephen Feather 2015-05-03

    "paperwork over progress"? Interesting view of process and procedures. Adam, please understand that had the pull request not been so inflated with unrelated" features" you would be able to more easily add the requested feature this ticket specifically addressed to your own tisdk build until it is pulled into master. To the point, if the original pr author believes the additional features have value, he should take the time to create tickets to make his case.
  21. Adam 2015-05-03

    As far as I can tell, the pull request adds three additional things pertaining to CFBundleIconFiles, UILaunchImages, and UIAppFonts wherein only these values are used when necessary. I doubt Fokke was trying to maliciously slip these into the build under the original pull request. I'm sure others would agree that the entire pull request is incredibly useful. If we really need issues created for each of the three additions, then perhaps someone could quickly do so. Even better, perhaps someone from Appcelerator could cherry-pick from his pull request if this is the major sticking point. I personally don't see this as a major hold up. In fact, we have already used his pull request applied to 3.5.1. It worked wonderfully and allowed us to quickly use TestFlight.
  22. Shannon Hicks 2015-05-03

    Obviously you are mistaken about it not being a major holdup, or the PR would have been merged already :)
  23. Adam 2015-05-03

    Shannon, as I said... I don't see it as a major hold up, but I guess appcelerator does! :) Perhaps they can cherry-pick the parts that pertain to this issue though so it gets pushed through.
  24. Stephen Feather 2015-05-03

    Who said anything about 'malicious' intent on Fokke's part? Having seen good PRs languish and die around here over missing JIRAs, I'm saying the past expectations should be met regarding PRs. Other wise, the PR process becomes rather arbitrary. Wait, someone (farfromrefug) raised the versioning problem over a YEAR AGO and that attempt to fix died because of a missing JIRA ticket (adam's paperwork comment applies here). Wait, someone else (me) pushed versioning changes when Testflight first went live. Trust me, Adam, I have an interest in getting versioning correct. Why the issue keeps creeping back into Ti totally frustrates those of us that build real apps in real production environments.
  25. Shannon Hicks 2015-05-03

    The problem is limited resources. Everything has to be tested, regression tested, etc in order to make it into one of Appcelerator's certified (official) builds. So, when something has "extra features" beyond what a JIRA ticket requires, it gets thrown to the bottom of the priority list because of the mess of additional work to be done. I'd do the same thing in my OSS projects. Even the idea of them cherry-picking a part of the PR is a big ol' can of worms. People have complained before (and rightfully so) when their PRs got modified by Appcelerator... what happens is that an Appcelerator employee ends up, git-wise, getting credit for the PR instead of the original author. So, unless a PR is merge-ready, as-is, it's always going to be a problem.
  26. Fokke Zandbergen 2015-05-03

    To make sure no toes get hurt in the process: * New PR on master: [#6818](https://github.com/appcelerator/titanium_mobile/pull/6818) * Re-purposed the original PR [#6408](https://github.com/appcelerator/titanium_mobile/pull/6408) for a new issue on the bigger story: TIMOB-18868
  27. Chris Barber 2015-05-03

    I reviewed this PR and talked over the changes with Fokke, then did a full pass of functional testing. It properly allows users to override the CFBundleVersion and CFBundleShortVersionString via the custom Info.plist and the section of the tiapp.xml. The PR also addressed other Info.plist values that were not user-overwritable. These additions are rational and welcome.
  28. Adam 2015-05-03

    Chris and Fokke: Thank you for your hard work on this!
  29. Ingo Muschenetz 2015-05-04

    All, thank you very much for assisting with this effort. I have marked this for merge-4.0.0 and we will discuss that on Monday.
  30. Eric Wieber 2015-07-06

    Verified fixed, using: MacOS 10.11 Studio 4.1.0.201507031129 Ti SDK 4.1.0.v20150706073311 Appc NPM 4.1.0-1 Appc CLI 4.1.0-5 Ti CLI 4.0.1 Alloy 1.6.2 Node v0.10.37 Java 1.7.0_45 preproduction Am able to set both bundle version strings via tiapp.xml or custom plist. Strings can be separate values and tested uploading to iTunes Connect, checking versions.

JSON Source