PBXProject是Unity官方提供的一组对XCode工程配置文件project.pbxproj的增删改查接口。结合OnPostprocessBuild方法,可以在Unity打包出XCode工程后,通过代码对XCode工程进行设置。常用的有添加库,修改BuildSettings等功能,网上资料比较多,这里就不赘述了。
本篇分享主要是记录一下使用PBXProject设置XCode中一些特殊选项的思路,按照此方法,理论上可以将所有XCode工程中的操作用代码自动实现。
本次分享主要是针对一个比较特殊的需求展开。需求如下:
要将Unity工程打包成.framework库,但是一些文件的Target Membership设置默认都是不勾选UnityFramework的,需要用代码将UnityFramework勾选上。
首先对project.pbxproj文件的格式得有个基本认知,最外层的结构如下,是一种类似Json的存储格式,使用 UUID作为索引 (可以当作Unity中Assets的GUID去理解,总之就是资源根据某些规则生成的唯一索引), 保证每个配置信息对象的唯一性。
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
};
rootObject = xxxxxx /* Project object */;
}
主要配置内容存储在objects中,详情下面的链接整理得非常细了,下文只举例用例中用到一部分。
Xcode工程文件的格式说明
我们的需求本质上是用代码操控配置文件,达到和在XCode编辑器UI上勾选一样的效果。而具体要修改哪里,实践出真知,最简单的方法就是在XCode编辑器中,勾选我们需要的选项,然后对比配置文件前后发生的变化。
/*Begin PBXResourcesBuildPhase section */
Resources的UUID /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
Data文件夹的UUID /* Data in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
//同结构不同UUID的结构还有两个 这里省略了
/*End PBXResourcesBuildPhase section */
UnityFramework的UUID /* UnityFramework*/ = {
isa = PBXNativeTarget;
buildConfigurationList = C01FCF4A08A954540054247B
/* Build configuration list for PBXNativeTarget "UnityFramework" */;
buildPhases = (
xxxxxxxxxxxxxxxxxxxxxxxx/* Sources */,
xxxxxxxxxxxxxxxxxxxxxxxx/* Frameworks*/,
xxxxxxxxxxxxxxxxxxxxxxxx/* Headers*/,
xxxxxxxxxxxxxxxxxxxxxxxx/* ShellScript*/,
Resources的UUID/* Resources */,
);
//省略了不相关的部分
}
//省略了很多
projectRoot = "",
targets = {
Unity-iPhone的UUID /*"Unity-iPhone" */
Unity-iPhone Test的UUID /*"Unity-iPhone Test" */
UnityFramework的UUID /*"UnityFramework" */
}
于是我们的层级关系和要做的事就很明朗了,我们要做的就是在配置文件下的UnityFramework/Resources/PBXResourcesBuildPhase Section/files列表中加入Data文件夹的UUID查一查API(其实还挺麻烦的,因为官方的文档有点难理解,翻了源码才找到)最后实现如下
//获取UnityFramework的UUID
frameTarget = project.GetUnityFrameworkTargetGuid();
//获取UnityFramework下的PBXResourcesBuildPhase Section UUID
string resourceTarget = project.GetResourcesBuildPhaseByTarget(frameTarget);
//根据Data目录相对路径获取UUID
resGUID = project.FindFileGuidByProjectPath("Data");
//添加Data UUID进file目录
project.AddFileToBuildSection(frameTarget, resourceTarget, resGUID);
简单的需求,重在记录分享思路,感谢看到最后的大家!