#Unity# 在编辑器扩展中用PostProcessBuildAttribute来修改XCode工程的Product Name
问题环境
之前用Unity打包上传时遇到过一个问题:
《 #Unity# iOS打包上传时报错 The bundle uses a bundle name or display name that is already taken 》
在解决这个bundle name冲突的时候,提到需要手动修改Product Name,以避免与系统名字冲突。
但是,Unity输出工程时,每次都会覆盖这些设置,如果每次手动修改还是挺麻烦的。
那么,有没有办法可以自动化呢?
解决方法
自动化的方法,就是利用Unity的编辑器扩展脚本,参考另一篇文章:
再加上Unity提供的打包工作流脚本插件
PostProcessBuildAttribute: Add this attribute to a method to get a notification just after building the player.
利用这个脚本,就可以在打包的时候对XCode工程进行修改了。
要点讲解
- 格式
声明打包后需要执行的方法:
[PostProcessBuildAttribute]
public static void OnPostProcessBuild(BuildTarget target, string pathToBuildProject)
{
}
- 修改xcode 工程文件
1). 打开xcode工程
string pbxProjectPath = PBXProject.GetPBXProjectPath( pathToBuildProject );
// 修改工程设置
PBXProject pbxProject = new PBXProject();
pbxProject.ReadFromFile( pbxProjectPath );
2). 读取设置,这里读取 PRODUCT_BUNDLE_IDENTIFIER 和 PRODUCT_NAME
PBXProject pbxProject = new PBXProject();
pbxProject.ReadFromFile( pbxProjectPath );
// 读取 build target
string targetGUID = pbxProject.TargetGuidByName(PBXProject.GetUnityTargetName() );
// 读取具体属性设置
var bundleId = pbxProject.GetBuildPropertyForAnyConfig(targetGUID, "PRODUCT_BUNDLE_IDENTIFIER");
var productName = pbxProject.GetBuildPropertyForAnyConfig(targetGUID, "PRODUCT_NAME");
3). 修改设置
string newProductName = "doufxcamera"; // 注意product name必须都小写
if(productName != newProductName){
pbxProject.SetBuildProperty(targetGUID, "PRODUCT_NAME", newProductName);
}
4). 保存
File.WriteAllText( pbxProjectPath, pbxProject.WriteToString() );
- 修改Info.plist文件
注意:如果只修改PRODUCT_NAME,会发现我们设置的BundleId也被修改了,因为Unity的XCode工程中,Info.plist中BundleId是与PRODUCT_NAME相关的。
步骤与修改工程文件类似
1). 打开文件
string plistPath = Path.Combine( pathToBuildProject, "Info.plist" );
PlistDocument plist = new PlistDocument();
plist.ReadFromString( File.ReadAllText( plistPath ) );
PlistElementDict rootDict = plist.root;
2). 读取或者修改字段
rootDict.SetString("CFBundleIdentifier", bundleId);
3). 保存
File.WriteAllText( plistPath, plist.WriteToString() );
- 完整代码参考
[PostProcessBuildAttribute]
public static void OnPostProcessBuild(BuildTarget target, string pathToBuildProject)
{
if (target == BuildTarget.iOS)
{
Debug.Log( "[PostBuild] pathToBuildProject: " + pathToBuildProject );
string pbxProjectPath = PBXProject.GetPBXProjectPath( pathToBuildProject );
// 修改工程设置
PBXProject pbxProject = new PBXProject();
pbxProject.ReadFromFile( pbxProjectPath );
string targetGUID = pbxProject.TargetGuidByName( PBXProject.GetUnityTargetName() );
var bundleId = pbxProject.GetBuildPropertyForAnyConfig(targetGUID, "PRODUCT_BUNDLE_IDENTIFIER");
var productName = pbxProject.GetBuildPropertyForAnyConfig(targetGUID, "PRODUCT_NAME");
string newProductName = "doufxcamera";
Debug.LogFormat("[PostBuild] bundleid = {0}, product name={1}, change product name to: {2}", bundleId, productName, newProductName);
if(productName != newProductName){
pbxProject.SetBuildProperty(targetGUID, "PRODUCT_NAME", newProductName);
}
File.WriteAllText( pbxProjectPath, pbxProject.WriteToString() );
// 修改plist
string plistPath = Path.Combine( pathToBuildProject, "Info.plist" );
PlistDocument plist = new PlistDocument();
plist.ReadFromString( File.ReadAllText( plistPath ) );
PlistElementDict rootDict = plist.root;
rootDict.SetString("CFBundleIdentifier", bundleId);
File.WriteAllText( plistPath, plist.WriteToString() );
}
}