Unity通过PBXProject生成XCode工程

Unity版本:2020.3.47f1

首先通过PostProcessBuildAttribute监听XCode工程导出完成事件,GetUnityMainTargetGuid是获取XCode工程中"Unity-iPhone"对应的target,GetUnityFrameworkTargetGuid则对应"UnityFramework",在unity中大部分操作会是针对UnityFramework。PBXProject的很多操作都是通过guid的,下面会出现各种各样的guid。

下面是基础代码:

复制代码
static PBXProject pbxProject;
static string mainTarget;
static string frameworkTarget;
[PostProcessBuildAttribute]
public static void OnPostprocessBuild(BuildTarget buildTarget, string path)
{
    if (buildTarget == BuildTarget.iOS)
    {
string pbxProjectPath = PBXProject.GetPBXProjectPath(path); pbxProject
= new PBXProject(); pbxProject.ReadFromString(File.ReadAllText(pbxProjectPath)); mainTarget = pbxProject.GetUnityMainTargetGuid();//这个对应target中的Unity-iPhone frameworkTarget = pbxProject.GetUnityFrameworkTargetGuid();//这个对应target中UnityFramework //...
//你的操作
//...
     pbxProject.WriteToFile(pbxProjectPath);  //操作完后要写回文件,否则无效 } }
复制代码

 

一、BuildSettings

使用SetBuildProperty设置BuildSettings中的设置,参数分别为target、设置名、设置值,其中设置名可以参考这里,比如:

pbxProject.SetBuildProperty(mainTarget, "ENABLE_BITCODE", "NO");
pbxProject.SetBuildProperty(frameworkTarget, "ENABLE_BITCODE", "NO");

如果需要对Debug、Release分别设置,使用BuildConfigByName和SetBuildPropertyForConfig即可,比如:

string debugConfig = pbxProject.BuildConfigByName(mainTarget, "Debug");//Debug、Release、ReleaseForProfiling、ReleaseForRunning
pbxProject.SetBuildPropertyForConfig(debugConfig , "ENABLE_BITCODE", "NO");

 BuildSettings中的所有设置都可以通过上面两个方法设置,包括签名等设置,签名后面单独写。

二、BuildPhases

1、加入至CopyBundleResources

使用AddFile和AddFileToBuild,如下代码,GoogleService-Info.plist与Unity-iPhone.xcodeproj在同一级目录下,下面代码只加到了mainTarget中,如有需要也可加入frameworkTarget

string filePath = "GoogleService-Info.plist";
string fileGuid = pbxProject.AddFile(filePath, filePath, PBXSourceTree.Source);
pbxProject.AddFileToBuild(mainTarget, fileGuid);

2、加入至CompileSources

代码都需要加入到这里,注:AppleLogin.m在Apple目录中,Apple与Unity-iPhone.xcodeproj在同一级目录,不需要对Apple文件夹做任何操作,不要使用"Apple/AppleLogin.m",否则会找不着路径,必须使用Path.Combine。

string filePath = Path.Combine("Apple", "AppleLogin.m");
string fileGuid = pbxProject.AddFile(filePath, filePath, PBXSourceTree.Source);
var sourcesBuildPhase = pbxProject.GetSourcesBuildPhaseByTarget(mainTarget);
pbxProject.AddFileToBuildSection(target, sourcesBuildPhase, fileGuid);

3、LinkBinaryWithLibraries

这块会比较复杂,要分开为4种情况

·系统Framework

使用AddFrameworkToProject,函数很简单,三个参数分别是target、framework名、是否为弱引用,framework名必须以".framework"结尾,弱引用为false时对应xcode中的Required

pbxProject.AddFrameworkToProject(frameworkTarget, "AdSupport.framework", false);

·SwiftPackageManager中的Framework

当工程中用到了SwiftPakcageManager则需要调用以下方法,如下面用到的是Firebase包中的三个framework,Remote相关接口是在Unity2020.3.42新加的,具体可查看官方文档。其中AddRemotePackageFrameworkToProject既是添加到LinkBinaryWithLibraries中,framework的名字不带任何后缀

string firebaseGuid = pbxProject.AddRemotePackageReferenceAtVersion("https://github.com/firebase/firebase-ios-sdk", "10.8.1");
pbxProject.AddRemotePackageFrameworkToProject(frameworkTarget, "FirebaseMessaging", firebaseGuid, false);
pbxProject.AddRemotePackageFrameworkToProject(frameworkTarget, "FirebaseAnalytics", firebaseGuid, false);
pbxProject.AddRemotePackageFrameworkToProject(frameworkTarget, "FirebaseCrashlytics", firebaseGuid, false);

·target作为Framework

由于前面的remoteFramework全部是添加至frameworkTarget中,mainTarget中的代码可能会报错,如果mainTarget中也添加一次,会报两个target中有重复代码的提示,但依然可以编译通过,运行时会有比较诡异的情况发生,比如FirebaseCloudMessaging中的注册token会每次启动都更新,解决方法是把UnityFramework添加至Unity-iPhone的LinkBinaryWithLibraries中,代码如下:

string file = "UnityFramework.framework";
string fileGuid = pbxProject.AddFile(file, file, PBXSourceTree.Build);
if (fileGuid != null)
{
    var sourcesBuildPhase = pbxProject.GetFrameworksBuildPhaseByTarget(mainTarget);
    pbxProject.AddFileToBuildSection(mainTarget, sourcesBuildPhase, fileGuid);
}

·本地Framework

本地Framework也有点特殊,调用的是AddFileToBuild,注:FBAudienceNetwork.framework在sdks目录中,sdks与Unity-iPhone.xcodeproj同一级,不需要单独添加sdks这个目录,否则会找不着所添加的framework

string filePath = Path.Combine("sdks", "FBAudienceNetwork.framework");
string fileGuid = pbxProject.AddFile(filePath, filePath, PBXSourceTree.Source);
pbxProject.AddFileToBuild(frameworkTarget, fileGuid);

三、Info.plist

Info.plist比较简单,修改OnPostprocessBuid方法,新加如info.plist读取

复制代码
static PBXProject pbxProject;
static string mainTarget;
static string frameworkTarget;

static PlistDocument plist;

[PostProcessBuildAttribute]
public static void OnPostprocessBuild(BuildTarget buildTarget, string path)
{
    if (buildTarget == BuildTarget.iOS)
    {
        string pbxProjectPath = PBXProject.GetPBXProjectPath(path);
        pbxProject = new PBXProject();
        pbxProject.ReadFromString(File.ReadAllText(pbxProjectPath));
        mainTarget = pbxProject.GetUnityMainTargetGuid();//这个对应target中的Unity-iPhone
        frameworkTarget = pbxProject.GetUnityFrameworkTargetGuid();//这个对应target中UnityFramework

        string plistPath = xcodeProjectPath + "/Info.plist";
        plist = new PlistDocument();
        plist.ReadFromString(File.ReadAllText(plistPath));

        //...
        //你的操作
        //...
       pbxProject.WriteToFile(pbxProjectPath);  //操作完后要写回文件,否则无效
        plist.WriteToFile(plistPath);//plist也要写回文件
    }
}

复制代码

plist的修改需要结合文件本身的结构,推荐先在xcode中操作后,看plist中结构是怎么样的,再利用unity提供的接口进行修改

四、Capabilities

待续

五、签名

待续

六、其他

posted @   muhoor  阅读(1327)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
点击右上角即可分享
微信分享提示