最近在工作中遇到了一些集成 SDK 的问题,由于整个框架都是自动化的,所以 SDK 得集成也需要把所需的编译环境和启动代码写在 Unity 的脚本中。这两天也查找了很多资料,最终完成了集成,在这里记录一下过程和重点。
主要使用的方法
public class iOSPostProcessBuild
{
//该属性是在build完成后,被调用执行的
[PostProcessBuild]
public static void OnPostprocessBuild(BuildTarget buildTarget, string pathToBuildProject)
{
if (buildTarget != BuildTarget.iOS)
return;
//初始化
string projectPath = pathToBuildProject + "/Unity-iPhone.xcodeproj/project.pbxproj";
PBXProject pbxProj = new PBXProject();
pbxProj.ReadFromFile(projectPath);
string targetGuid = pbxProj.TargetGuidByName("Unity-iPhone");
...
//保存所有修改
pbxProject.WriteToFile(projectPath);
}
}
在 [PostProcessBuild] 下的方法会在build完成之后被调用,在这个方法对 XCode 工程的编译选项和 plist 文件进行编辑。
对 XCode 的编译选项进行操作
需要引入 UnityEditor.iOS.Xcode 命名空间。
//添加flag
pbxProj.AddBuildProperty(targetGuid, "OTHER_LDFLAGS", "-ObjC");
//关闭BitCode
pbxProj.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO");
//添加framwork
pbxProj.AddFrameworkToProject(targetGuid, "CFNetwork.framework", false);
//添加lib
pbxProj.AddFileTobuild(targetGuid, pbxProj.AddFile("usr/lib/libsqlite3.tbd", "Frameworks/libsqlite3.tbd", PBXSourceTree.Sdk));
//应用修改
File.WriteAllText(projectPath, pbxProj.WriteToString());
修改Info.plist文件
string plistPath = Path.Combine(pathToBuildProject, "Info.plist");
PlistDocument plist = new PlistDocument();
plist.ReadFromFile(plistPath);
PlistElementDict rootDict = plist.root;
// NSAppTransportSecurity
const string nsappKey = "NSAppTransportSecurity";
PlistElementDict nsappDic;
PlistElement nspel;
if (rootDict.values.TryGetValue(nsappKey, out nspel))
nsappDic = nspel.AsDict();
else
nsappDic = rootDict.CreateDict(nsappKey);
nsappDic.SetBoolean("NSAllowsArbitraryLoads", true);
// 应用修改
File.WriteAllText(plistPath, plist.WriteToString());
修改OC代码
namespace XCodeBuilder.XCodeEditor
{
public partial class XCodeClass : System.IDisposable
{
private string filePath;
public XCodeClass(string fPath)
{
filePath = fPath;
if (!System.IO.File.Exists(filePath))
{
Debug.LogError(filePath + "路径下文件不存在");
return;
}
}
public void WriteBelow(string below, string text)
{
StreamReader sr = new StreamReader(filePath);
string text_all = sr.ReadToEnd();
sr.Close();
int beginIndex = text_all.IndexOf(below);
if (beginIndex == -1)
{
Debug.LogError(filePath + "中没有找到标致" + below);
return;
}
int endIndex = text_all.LastIndexOf("\n", beginIndex + below.Length);
text_all = text_all.Substring(0, endIndex) + "\n" + text + "\n" + text_all.Substring(endIndex);
StreamWriter sw = new StreamWriter(filePath);
sw.Write(text_all);
sw.Close();
}
public void Replace(string below, string newText)
{
StreamReader sr = new StreamReader(filePath);
string text_all = sr.ReadToEnd();
sr.Close();
int beginIndex = text_all.IndexOf(below);
if (beginIndex == -1)
{
Debug.LogError(filePath + "中没有找到标致" + below);
return;
}
text_all = text_all.Replace(below, newText);
StreamWriter sw = new StreamWriter(filePath);
sw.Write(text_all);
sw.Close();
}
public void Dispose()
{
}
}
}
//插入代码
//读取UnityAppController.mm文件
string unityAppControllerPath = pathToBuildProject + "/Classes/UnityAppController.mm";
XCodeClass UnityAppController = new XCodeClass(unityAppControllerPath);
//在指定代码后面增加一行代码
UnityAppController.WriteBelow("指定代码", "需要添加的代码");
//在指定代码后面增加一大行代码
string newCode = "需\n" +
"要\n" +
"添\n" +
"加\n" +
"的\n" +
"大段代码。";
UnityAppController.WriteBelow("指定代码", newCode);
添加自定义类库
//将库文件从Assets中拷贝到XCode工程中
public static void CopyDirectory(string srcPath, string dstPath, string[] excludeExtensions, bool overwrite = true)
{
if (!Directory.Exists(dstPath))
Directory.CreateDirectory(dstPath);
foreach (var file in Directory.GetFiles(srcPath, "*.*", SearchOption.TopDirectoryOnly))
{
File.Copy(file, Path.Combine(dstPath, Path.GetFileName(file)), overwrite);
}
foreach (var dir in Directory.GetDirectories(srcPath))
CopyDirectory(dir, Path.Combine(dstPath, Path.GetFileName(dir)), excludeExtensions, overwrite);
}
#region 添加资源文件(中文路径 会导致 project.pbxproj 解析失败)
string frameworksPath = Application.dataPath + "库文件所在的文件夹";
string[] directories = Directory.GetDirectories(frameworksPath, "*", SearchOption.TopDirectoryOnly);
for (int i = 0; i < directories.Length; i++)
{
string path = directories[i];
string name = path.Replace(frameworksPath + "/", "");
string destDirName = pathToBuildProject + "目标路径" + name;
if (Directory.Exists(destDirName))
Directory.Delete(destDirName, true);
Debug.Log(path + " => " + destDirName);
CopyDirectory(path, destDirName, new string[] { ".meta", ".framework", ".bundle", ".mm", ".c", ".m", ".h", ".xib", ".a", ".plist", ".org", "" }, false);
foreach (string file in Directory.GetFiles(destDirName, "*.*", SearchOption.AllDirectories))
{
pbxProject.AddFileToBuild(targetGuid, pbxProject.AddFile(destDirName, "目标路径" + name, PBXSourceTree.Sdk));
pbxProject.AddBuildProperty(targetGuid, "FRAMEWORK_SEARCH_PATHS", "$(SRCROOT)" + "目标路径");
pbxProject.AddBuildProperty(targetGuid, "HEADER_SEARCH_PATHS", "$(SRCROOT)" + "目标路径");
pbxProject.AddBuildProperty(targetGuid, "LIBRARY_SEARCH_PATHS", "$(SRCROOT)" + "目标路径");
}
}
#endregion
Unity3D 通过代码控制编译 XCode 工程
https://白日梦.cn/2018/06/22/CyPPMxRa
评论