From Unity to iOS, how to perfectly automate frameworks, settings and plist?
IMPORTANT:
Very unfortunately you can not use System.xml here as you would expect, since, Apple's plist format is insane. You probably have to use a munge.
For 2019 ...
Filename, BuildPostProcessor.cs
Put it in the folder Assets/Editor/ . (Just make the folder "Editor/" exactly there if it does not exist.)
This shows how to do all three of frameworks, settings and plist.
// filename BuildPostProcessor.cs
// put it in a folder Assets/Editor/
using System.IO;
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
public class BuildPostProcessor {
[PostProcessBuild]
public static void ChangeXcodePlist(BuildTarget buildTarget, string path) {
if (buildTarget == BuildTarget.iOS) {
string plistPath = path + "/Info.plist";
PlistDocument plist = new PlistDocument();
plist.ReadFromFile(plistPath);
PlistElementDict rootDict = plist.root;
Debug.Log(">> Automation, plist ... <<");
// example of changing a value:
// rootDict.SetString("CFBundleVersion", "6.6.6");
// example of adding a boolean key...
// < key > ITSAppUsesNonExemptEncryption </ key > < false />
rootDict.SetBoolean("ITSAppUsesNonExemptEncryption", false);
File.WriteAllText(plistPath, plist.WriteToString());
}
}
[PostProcessBuildAttribute(1)]
public static void OnPostProcessBuild(BuildTarget target, string path) {
if (target == BuildTarget.iOS) {
PBXProject project = new PBXProject();
string sPath = PBXProject.GetPBXProjectPath(path);
project.ReadFromFile(sPath);
string tn = PBXProject.GetUnityTargetName();
string g = project.TargetGuidByName(tn);
ModifyFrameworksSettings(project, g);
// modify frameworks and settings as desired
File.WriteAllText(sPath, project.WriteToString());
}
}
static void ModifyFrameworksSettings(PBXProject project, string g) {
// add hella frameworks
Debug.Log(">> Automation, Frameworks... <<");
project.AddFrameworkToProject(g, "blah.framework", false);
project.AddFrameworkToProject(g, "libz.tbd", false);
// go insane with build settings
Debug.Log(">> Automation, Settings... <<");
project.AddBuildProperty(g,
"LIBRARY_SEARCH_PATHS",
"../blahblah/lib");
project.AddBuildProperty(g,
"OTHER_LDFLAGS",
"-lsblah -lbz2");
// note that, due to some Apple shoddyness, you usually need to turn this off
// to allow the project to ARCHIVE correctly (ie, when sending to testflight):
project.AddBuildProperty(g,
"ENABLE_BITCODE",
"false");
}
}
That will do it.
Note - the final part of the puzzle is copying across files (perhaps data files or text files). In reality it's best to just use the "StreamingAssets/" approach, explained fully in this QA.
Fixed code for Unity 2019.3:
// filename BuildPostProcessor.cs
// put it in a folder Assets/Editor/
using System.IO;
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
public class BuildPostProcessor
{
[PostProcessBuild]
public static void ChangeXcodePlist(BuildTarget buildTarget, string path)
{
if (buildTarget == BuildTarget.iOS)
{
string plistPath = path + "/Info.plist";
PlistDocument plist = new PlistDocument();
plist.ReadFromFile(plistPath);
PlistElementDict rootDict = plist.root;
Debug.Log(">> Automation, plist ... <<");
// example of changing a value:
// rootDict.SetString("CFBundleVersion", "6.6.6");
// example of adding a boolean key...
// < key > ITSAppUsesNonExemptEncryption </ key > < false />
rootDict.SetBoolean("ITSAppUsesNonExemptEncryption", false);
File.WriteAllText(plistPath, plist.WriteToString());
}
}
[PostProcessBuildAttribute(1)]
public static void OnPostProcessBuild(BuildTarget target, string path)
{
if (target == BuildTarget.iOS)
{
PBXProject project = new PBXProject();
string sPath = PBXProject.GetPBXProjectPath(path);
project.ReadFromFile(sPath);
string g = project.GetUnityFrameworkTargetGuid();
ModifyFrameworksSettings(project, g);
// modify frameworks and settings as desired
File.WriteAllText(sPath, project.WriteToString());
}
}
static void ModifyFrameworksSettings(PBXProject project, string g)
{
// add hella frameworks
Debug.Log(">> Automation, Frameworks... <<");
project.AddFrameworkToProject(g, "blah.framework", false);
project.AddFrameworkToProject(g, "libz.tbd", false);
// go insane with build settings
Debug.Log(">> Automation, Settings... <<");
project.AddBuildProperty(g,
"LIBRARY_SEARCH_PATHS",
"../blahblah/lib");
project.AddBuildProperty(g,
"OTHER_LDFLAGS",
"-lsblah -lbz2");
// note that, due to some Apple shoddyness, you usually need to turn this off
// to allow the project to ARCHIVE correctly (ie, when sending to testflight):
project.AddBuildProperty(g,
"ENABLE_BITCODE",
"false");
}
}