What is bundle version and short bundle version?

Hi,

there are two bundle versions in Edit > Project Settings > Player Settings > Other Settings.

When I change bundle version. Must I change short bundle version to the same string like in bundle version?

Short Bundle Version should only be visible on iOS not on other platforms, this might be a bug in 4.6.x - and it’s not available in 5.0 which is also a bug but here is the explanation what it is:

Short Bundle Version is the version number e.g. 1.0.3 and Bundle Version is the build number which could be 42 for example or 1.0.3b12.

While Bundle Version Code (on Android) is the build version which could be 42 for example as integer.

Bundle Version (Code) is used on iOS and Android for example during testing plans, to increase the version by an automated system e.g. Testlfight, Hockeyapp, Unity Cloud Build. For testing you set the Short Bundle Version to the final version number like 1.0.3 and then increment the Bundle Version (Code) for each build.

On iOS - Short Bundle Version (CFBundleShortVersionString) represents a release version, whereas Bundle Version (CFBundleVersion) represents any build, released or not. Also, Short Bundle Version (CFBundleShortVersionString) can be localized (not everything is modern arabic).

1 Like

Hey David-

Is control of CFBundleVersion coming back to Unity 5.x for iOS anytime soon?

We’re blocked on Unity Cloud Build because we can’t figure out a way to set the CFBundleVersion from in the Unity Editor - we need to be able to increment the CFBundleVersion from the Editor so that we can deploy our builds created from Cloud Build.

I assume you are aware of the core problem - that, starting in Unity 5.0, the current Bundle Version field in the Unity Editor sets both the CFBundleVersion and CFBundleShortVersionString in the resulting Xcode project / Cloud Build IPA file to the same number. This is in conflict with the iTunesConnect hard-enforced requirement that the CFBundleVersion must increment with every build (introduced late last year with Apple’s native Test Flight implementation).

(There is probably some way to do this with PostprocessBuildplayer? But we aren’t very savvy in this area. If you can link examples, please do.)

I can provide more info about the core problem if you are unfamiliar. But my basic question remains: how do we control the CFBundleVersion in Unity 5.x?

-sean

We are aware of the problem and we currently work on ways to get it to 5.0 but no ETA yet. Regardless of Unity Cloud Build, you should be able to set the number in your XCode project with a post process step using the XCode manipulation API which should work in UCB too afterwards.

Hi David!

Can you provide some information about how to do this with UCB, or even step-by-step instructions? We do not have access to the Xcode project with UCB - right?

What we want is the same “build number” shared on Android and iOS - so we can set a build number in Unity Editor and ensure it is incremented across platforms. (Sharing a build number across platforms also makes good sense to us in terms of keeping our workflow “sane”.) Alternately it would be OK if there is a separate field in the editor for us to use that is dedicated to iOS.

Any help you can provide would surely help us and others. Thank you!

-sean

In particular, with the Xcode Manipulation API, I do not understand how to download it, where to put it, what script to call the API from, etc. Essentially: I do not understand how to use it.

The readme on both these projects is essentially empty, and the folder structure doesn’t make sense to me:

https://bitbucket.org/Unity-Technologies/xcodeapi/src/

https://bitbucket.org/Unity-Technologies/iosnativecodesamples/src/

…and so I am at a loss on how to proceed.

I don’t think you can use the XCode manipulation API with PBXProject to change it, as it’s not stored in the XCode project. The CFBundleShortVersionString and CFBundleVersion are stored in the Info.plist.

You can have a look here xcode - Localize iOS App name in Unity - Stack Overflow It’s not exactly what you need but it gives you a good overview what you can do with post process execution.

For Unity Cloud Build I would recommend to use post process attributes as you can test them also locally. See Native Library Demo in UCB Demos. In this demo I use the XCode Manipulation API to add some libraries and modify the XCcode project, but instead of the PBXProject you need to use the PlistDocument in PlistParser I think to modify the Info.plist.

Hey David, et al,

We were able to solve this with the following steps. I would recommend putting something like this (especially the install steps!) in the readme files on the BitBucket repos.

Step 1 - Install Xcode Manipulation API project files
To install the Xcode Manipulation API, create a new folder under Assets > Editor called something like Xcode Manipulation API. Then, copy the source files from the following BitBucket repo to the new subfolder that you created in the Editor folder:

https://bitbucket.org/Unity-Technologies/xcodeapi/src/

Step 2 - Install Xcode Manipulation API DLLs

To install the Xcode Manipulation API DLLs, first go here:

https://bitbucket.org/Unity-Technologies/iosnativecodesamples/src/ae6a0a2c02363d35f954d244a6eec91c0e0bf194/NativeIntegration/Misc/UpdateXcodeProject/Assets/Editor?at=5.0-dev

NOTE: The link above is for Unity 5.0 - if you use a different version of Unity, select a different branch (e.g. 4.5-stable) before proceeding.

Download Unity.iOS.Extensions.Xcode.dll and XcodeProjectUpdater.cs and copy them to your project’s Editor folder (same one as in Step 1, but not in the subfolder that you created).

Step 3 - Code.

Use the example code in XcodeProjectUpdater.cs, but note that you must delete the entire contents of that file and replace it with your desired code. For example, we use XcodeProjectUpdater.cs to update the iOS “build number” - which is not allowed in the Unity Editor as of version 5.0.1 - and our complete file looks like this:

using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System.Collections;
using UnityEditor.iOS.Xcode;
using System.IO;

public class MyBuildPostprocessor {

    internal static string getAndroidBuildNumberString()
    {
        // find Android build number in the project
        int buildNumber = PlayerSettings.Android.bundleVersionCode;
        string buildString = buildNumber.ToString ();
        Debug.Log ("XCMAPI: reading PlayerSettings.Android.bundleVersionCode: " + buildString);

        return buildString;
    }

    [PostProcessBuild]
    public static void OnPostprocessBuild(BuildTarget buildTarget, string path) {

        Debug.Log("XCMAPI: OnPostprocessBuild() called...");
   
        if (buildTarget == BuildTarget.iOS) {

            Debug.Log("XCMAPI: OMG. iOS update starting!");

            // find Android version number
            string buildString = MyBuildPostprocessor.getAndroidBuildNumberString();
            Debug.Log ("XCMAPI: found build number: " + buildString);

            // get Info.plist file
            string projPath = path + "/Info.plist";
            Debug.Log ("XCMAPI: looking for plist at: " + projPath);
           
            PlistDocument plist = new PlistDocument();
            plist.ReadFromString(File.ReadAllText(projPath));
            Debug.Log ("XCMAPI: found plist! " + plist);

            // TODO: figure out how to abort the build if the projPath is incorrect
            // if plist object is empty/zero size, maybe?

            // get existing build string
            PlistElementDict rootDict = plist.root;
            Debug.Log ("XCMAPI: found root dictionary! " + rootDict.AsDict());

            // overwrite key
            var buildKey = "CFBundleVersion";
            Debug.Log ("XCMAPI: current value of CFBundleVersion: " + rootDict[buildKey].AsString());

            rootDict.SetString(buildKey,buildString);
            Debug.Log ("XCMAPI: updated value of CFBundleVersion: " + rootDict[buildKey].AsString());

            // write file
            File.WriteAllText(projPath, plist.WriteToString());

        }
    }
}

That’s it! I hope that helps.

Also note, for anyone who needs to do anything different with their code, any change that I made to XcodeProjectUpdater.cs did NOT take effect until I either (a) closed and re-opened Unity entirely, or (b) committed the code change to git (in our case using Tower, which is a badass source control interface for git/GitHub).

-sean

3 Likes

For those who find this post in the future… I’m using Unity 5.1.1f1 and read in the docs that the XCode manipulation DLLs were already bundled. So I was just able to put @toblerpwn 's script into the Editor directly and it ran just fine.

For those of you using git I was able to follow Using Git to generate an automatic version number in combination with the above to have the XCode CFBundleVersion increment automatically every time there is a git commit.

Thanks @toblerpwn !

2 Likes

huge thanks to the previous two posts.
the fact that I can parse plist files is gold.