How does Unity Cloud build iOS handle modifications to the Xcode Project?

Hi there,

I am a solo developer and I am a little interested in cloud build as it seems it could remove a time consuming step for my pipeline. I just don’t quite understand how iOS builds could be automated completely.
Pretty much every time I’ve had to make an Xcode build, I’ve had to modify the Xcode project in some way to workaround an issue or add a feature from an asset or something.

How could that work with cloud build? Do you have some way of making those modifications yourself through cloud build?

Thanks!
Pete

1 Like

I’ve found that you don’t normally need to modify the project very often, it’s mostly the info.plist I have to add to. I’ve made some project updates before, mainly things like adding frameworks or modifying settings. You do all this through a ‘post process’ script that runs after the Unity build has finished but before the xCode compilation has started.

If the functionality you’re looking for is missing you can always do a hacky ‘string find/replace’ to modify the project file itself if it’s an edge case.

Here’s an example of a script I wrote, it modifies the plist file a bit (adds some keys) and then adds a few frameworks to the xCode project and disables bitcode. The file goes into Assets\Editor.

Even if you don’t use cloud build I find this is the best way to do it as you don’t have to manually fix the project every time you do a build in xCode. Also means you don’t forget important setting changes.

#if UNITY_IOS
using UnityEngine;
using UnityEditor.Callbacks;
using UnityEditor;
using UnityEditor.iOS.Xcode;
using System.IO;

public class ProvideExportCompliance
{
    [PostProcessBuild]
    public static void ChangeXcodePlist(BuildTarget buildTarget, string pathToBuiltProject)
    {
        // Performs any post build processes that we need done
        if( buildTarget == BuildTarget.iOS )
        {
            // PList modifications
            {
                // Get plist
                string plistPath = pathToBuiltProject + "/Info.plist";
                var plist = new PlistDocument();
                plist.ReadFromString(File.ReadAllText(plistPath));

                // Get root
                var rootDict = plist.root;

                // Add export compliance for TestFlight builds
                var buildKeyExportCompliance = "ITSAppUsesNonExemptEncryption";
                rootDict.SetString( buildKeyExportCompliance , "false" );
             
                // Add camera usage description (you can do this in Unity now anyway so just an example)
                var buildKeyCameraUsage = "NSCameraUsageDescription";
                rootDict.SetString( buildKeyCameraUsage , "Video recording plugin - not used in the app" );
             
                // Write to file
                File.WriteAllText( plistPath , plist.WriteToString() );
            }
         
            // xCode workspace modifications
            {
                // Get xCode Project
                string projectPath = pathToBuiltProject + "/Unity-iPhone.xcodeproj/project.pbxproj";
                PBXProject project = new PBXProject();
                project.ReadFromFile( projectPath );
                string targetGuid = project.GetUnityMainTargetGuid();
             
                // Add AdSupport(AdMob) & CloudKit(iCloud) framework
                project.AddFrameworkToProject( targetGuid , "iAd.framework" , false );
                project.AddFrameworkToProject( targetGuid , "CloudKit.framework" , false );
                project.AddFrameworkToProject( targetGuid , "CoreTelephony.framework" , false );
                project.AddFrameworkToProject( targetGuid , "AdSupport.framework" , false );
                project.AddFrameworkToProject( targetGuid , "AdServices.framework" , false );
             
                // Disable bitcode
                project.SetBuildProperty( targetGuid , "ENABLE_BITCODE" , "NO" );

                // Update xCode project to use the iCloud entitlements file and iCloud/AdSupport frameworks
                string projectString = project.WriteToString();
             
                // Save the xCode project file
                File.WriteAllText( projectPath , projectString );
            }
        }
    }
}
#endif
3 Likes

Awesome @tonemcbride ! That doesn’t look too bad, I’ll have a go.
Thanks so much,
P.

Works great! Thank-you!

Hi, I am using Cloud Build, is it means that I need to add the Post-build script path or Post-Export method in Cloud Build Advance Setting ? Because I found that our plist was not modify or change after the cloud build.

@elaine_unity694 If your project already uses a post-process method, then you don’t need to do anything else on the Cloud Build dashboard as that method will also execute when building on Cloud Build. You can also configure on the Cloud Build dashboard to execute a method after the Unity Editor exports your project. You can find more information here.

It’s the same with shell scripts. You can find the settings for both in the Advance settings on Cloud Build.

1 Like