It’s not Unity Cloud Build Specific, but as I wanted to make a tutorial already for a while, I’ll post it here. This is useful when you want to edit the Info.plist of an Xcode project built by Unity when building for iOS. This can be used for example to change the values of Version (CFBundleShortVersionString) and Build (CFBundleVersion) in an Xcode project from within Unity, as a build post-process.
You can now create a script such as the one below to alter CFBundleVersion in Xcode plist
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System.Collections;
using UnityEditor.iOS.Xcode;
using System.IO;
public class ChangeIOSBuildNumber {
[PostProcessBuild]
public static void ChangeXcodePlist(BuildTarget buildTarget, string pathToBuiltProject) {
if (buildTarget == BuildTarget.iOS) {
// Get plist
string plistPath = pathToBuiltProject + "/Info.plist";
PlistDocument plist = new PlistDocument();
plist.ReadFromString(File.ReadAllText(plistPath));
// Get root
PlistElementDict rootDict = plist.root;
// Change value of CFBundleVersion in Xcode plist
var buildKey = "CFBundleVersion";
rootDict.SetString(buildKey,"2.3.4");
// Write to file
File.WriteAllText(plistPath, plist.WriteToString());
}
}
}
Which sets the CFBundleVersion in your Info.plist in a post process step to “2.3.4” (works also in Unity Cloud Build in all Tiers).
I hope this makes sense and helps. Please let me know how it goes!
We are using it for background location and fetch stuff in a native plugin.
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System.Collections;
using UnityEditor.iOS.Xcode;
using System.IO;
public class MyPluginPostProcessBuild
{
[PostProcessBuild]
public static void ChangeXcodePlist(BuildTarget buildTarget, string pathToBuiltProject)
{
if ( buildTarget == BuildTarget.iOS )
{
// Get plist
string plistPath = pathToBuiltProject + "/Info.plist";
PlistDocument plist = new PlistDocument();
plist.ReadFromString(File.ReadAllText(plistPath));
// Get root
PlistElementDict rootDict = plist.root;
// background location useage key (new in iOS 8)
rootDict.SetString("NSLocationAlwaysUsageDescription", "Uses background location");
// background modes
PlistElementArray bgModes = rootDict.CreateArray("UIBackgroundModes");
bgModes.AddString("location");
bgModes.AddString("fetch");
// Write to file
File.WriteAllText(plistPath, plist.WriteToString());
}
}
}
Need some clarification.
Do I need to download the XcodeAPI and include it in my project if we are already using Unity 5 (5.0.2p3)? It already seems to be included, though I’m guessing it’s not the newest version.
Would this work with 4.6.5? Would that require including the XcodeAPI like you instructed?
Am I correct in assuming this would also work with Unity Cloud Build?
Yes, there is also a XCode API for 4.6 and 5. If you use source code of the repro you can alter the framework if necessary and it can be optimised. Yes, it also works with Unity Cloud Build.
Thanks, i used the sample code shown above and was able to modify the Info.plist to add what i wanted.
The major issue was only understanding what’s the name of the element i need to be added
In my book, a good API is one that can be used straight away without reading through docs, etc… (naming conventions are good and it’s hard to find your way around).
But if you need something more fancy, you will have to write some code in a post process script. The xml format is easy to modify, compared to the xcodeproj, so you don’t really need a “manipulation api" if that makes sense?
You can have multiple manifests in your project and Unity merges them I think. That’s probably not possible on iOS, but there you have the XCode manipulation API
I’m getting lots of errors in PBXProject.cs, like:
Error CS0234: The type or namespace name CombinePaths' does not exist in the namespace UnityEditor.Utils’. Are you missing an assembly reference? (CS0234) (Assembly-CSharp-Editor)
@urfx yes @peterworth make sure you update the XCode Manipulation API to the correct version for 4.6 @chrs1885 What’s the plistPath pointing to? I assume path is the path handed over from the post process method?
That’s the version (latest commit) that gives me errors in Unity 4.6. Same ones that @peterworth mentioned: Namespace CombinePaths does not exist in namespace UnityEditor.Utils, etc. That’s why I thought when you mentioned right version you meant a commit version, I just assumed the latest was only written for Unity 5.
The latest commit should work properly. Did you add the source directly into Unity? That might be broken and might not work without modification I fear, best is to build the dll separately and include the resulting dll into the project. I’ll forward it to the devs, maybe they can fix it for the next release of the public API.
In the meantime if you need precompiled dlls with a working Unity Cloud Build project check out the examples in the UCB Demos for Unity 4 and Unity 5. It’s the Library Demo project which includes the dlls in the Editor folder of the subfolder project.