public static string AddStickerExtension( this PBXProject proj, string mainTargetGuid, string name, string bundleId, string infoPlistPath) { string ext = ".appex"; string str = proj.AddTarget(name, ext, "com.apple.product-type.app-extension.messages-sticker-pack"); foreach (string buildConfigName in proj.BuildConfigNames()) { string configGuid = proj.BuildConfigByName(str, buildConfigName); if (buildConfigName.Contains("Debug")) { proj.SetDefaultAppExtensionDebugBuildFlags(configGuid); } else { proj.SetDefaultAppExtensionReleaseBuildFlags(configGuid); } proj.SetBuildPropertyForConfig(configGuid, "INFOPLIST_FILE", infoPlistPath); proj.SetBuildPropertyForConfig(configGuid, "PRODUCT_BUNDLE_IDENTIFIER", bundleId); } proj.AddSourcesBuildPhase(str); proj.AddResourcesBuildPhase(str); proj.AddFrameworksBuildPhase(str); string sectionGuid = proj.AddCopyFilesBuildPhase(mainTargetGuid, "Embed App Extensions", "", "13"); proj.AddFileToBuildSection(mainTargetGuid, sectionGuid, proj.GetTargetProductFileRef(str)); proj.AddTargetDependency(mainTargetGuid, str); return(str); }
/// <summary> /// 修改Xcode工程配置 /// </summary> /// <param name="path">Xcode工程根目录</param> public static void ModifyProj(string path) { string projPath = PBXProject.GetPBXProjectPath(path); PBXProject pbxProj = new PBXProject(); pbxProj.ReadFromString(File.ReadAllText(projPath)); // 配置目标TARGETS string targetGuid = pbxProj.TargetGuidByName("Unity-iPhone"); // 添加系统框架.framework pbxProj.AddFrameworkToProject(targetGuid, "Vision.framework", false); pbxProj.AddFrameworkToProject(targetGuid, "CoreML.framework", false); pbxProj.AddFrameworksBuildPhase(targetGuid); /* 还是需要手动配置 * // 添加一般文件 * string fileName = "MobileNet.mlmodel"; //必须输出到 Build/Library 文件夹中 * string srcPath = Path.Combine("Assets/Plugins", fileName); * string dstPath = "Libraries/" + fileName; * File.Copy(srcPath, Path.Combine(path, dstPath)); * //pbxProj.AddFileToBuild(targetGuid, pbxProj.AddFile(fileName, dstPath, PBXSourceTree.Source)); //xcode报红 * //pbxProj.AddFileToBuild(targetGuid, pbxProj.AddFile(dstPath, fileName, PBXSourceTree.Source)); //加到了外面 * pbxProj.AddFileToBuild(targetGuid, pbxProj.AddFile(dstPath, dstPath, PBXSourceTree.Source)); //xcode报红 * * // GoogLeNetPlaces.mlmodel * string file1 = "GoogLeNetPlaces.mlmodel"; * string srcPath1 = Path.Combine("Assets/Plugins", file1); * string dstPath1 = "Libraries/" + file1; * File.Copy(srcPath, Path.Combine(path, dstPath1)); * pbxProj.AddFileToBuild(targetGuid, pbxProj.AddFile(dstPath1, dstPath1, PBXSourceTree.Source)); */ File.WriteAllText(projPath, pbxProj.WriteToString()); }
/// <summary> /// Creates a watch extension. /// </summary> /// <returns>The GUID of the new target.</returns> /// <param name="proj">A project passed as this argument.</param> /// <param name="mainTarget">The GUID of the main target to link the watch extension to.</param> /// <param name="name">The name of the watch extension.</param> /// <param name="bundleId">The bundle ID of the watch extension. The bundle ID must be /// prefixed with the parent watch app bundle ID.</param> /// <param name="infoPlistPath">Path to the watch extension Info.plist document.</param> public static string AddWatchExtension(this PBXProject proj, string mainTarget, string name, string bundleId, string infoPlistPath) { var newTargetGuid = proj.AddTarget(name, ".appex", "com.apple.product-type.watchkit2-extension"); foreach (var configName in proj.BuildConfigNames()) { var configGuid = proj.BuildConfigByName(newTargetGuid, configName); if (configName.Contains("Debug")) { SetDefaultWatchExtensionDebugBuildFlags(proj, configGuid); } else { SetDefaultWatchExtensionReleaseBuildFlags(proj, configGuid); } proj.SetBuildPropertyForConfig(configGuid, "PRODUCT_BUNDLE_IDENTIFIER", bundleId); proj.SetBuildPropertyForConfig(configGuid, "INFOPLIST_FILE", infoPlistPath); } proj.AddSourcesBuildPhase(newTargetGuid); proj.AddResourcesBuildPhase(newTargetGuid); proj.AddFrameworksBuildPhase(newTargetGuid); return(newTargetGuid); }
public static void ModifyProj(string path) { string projPath = PBXProject.GetPBXProjectPath(path); PBXProject pbxProj = new PBXProject(); // 配置目标 pbxProj.ReadFromString(File.ReadAllText(projPath)); string targetGuid = pbxProj.TargetGuidByName("Unity-iPhone"); // 添加内置框架 pbxProj.AddFrameworkToProject(targetGuid, "Security.framework", false); //weak: true:optional, false:required pbxProj.AddFrameworkToProject(targetGuid, "CoreLocation.framework", false); pbxProj.AddFrameworkToProject(targetGuid, "CoreTelephony.framework", false); pbxProj.AddFrameworkToProject(targetGuid, "GLKit.framework", false); pbxProj.AddFrameworksBuildPhase(targetGuid); // 添加.tbd pbxProj.AddFileToBuild(targetGuid, pbxProj.AddFile("usr/lib/libz.tbd", "Frameworks/libz.tbd", PBXSourceTree.Sdk)); pbxProj.AddFileToBuild(targetGuid, pbxProj.AddFile("usr/lib/libc++.tbd", "Frameworks/libc++.tbd", PBXSourceTree.Sdk)); // 设置teamID //... File.WriteAllText(projPath, pbxProj.WriteToString()); }
//添加 xcodeModel.frameworks 中指定的 framework shareSDK子平台的framework private static void AddXcodeModelFrameworks(MOBXCodeEditorModel xcodeModel, PBXProject xcodeProj, string xcodeTargetGuid, string xcodeTargetPath) { foreach (MOBPathModel pathModel in xcodeModel.frameworks) { if (pathModel.filePath.Contains(".framework") && !pathModel.filePath.Contains("MOBFoundation.framework")) { string frameworkPath = pathModel.filePath.Replace(pathModel.rootPath, ""); string savePath = xcodeTargetPath + frameworkPath; int tempIndex = frameworkPath.LastIndexOf("\\"); if (tempIndex == -1) { tempIndex = frameworkPath.LastIndexOf("/"); } string saveFrameworkPath = frameworkPath.Substring(0, tempIndex); //将 framework copy到指定目录 DirectoryInfo frameworkInfo = new DirectoryInfo(pathModel.filePath); DirectoryInfo saveFrameworkInfo = new DirectoryInfo(savePath); CopyAll(frameworkInfo, saveFrameworkInfo); //将 framework 加入 proj中 xcodeProj.AddFileToBuildSection(xcodeTargetGuid, xcodeProj.AddFrameworksBuildPhase(xcodeTargetGuid), xcodeProj.AddFile(frameworkPath.Substring(1), "MOB" + frameworkPath, PBXSourceTree.Absolute)); //将 build setting 设置 xcodeProj.AddBuildProperty(xcodeTargetGuid, "FRAMEWORK_SEARCH_PATHS", "$(SRCROOT)" + saveFrameworkPath.Replace("\\", "/")); } else { Debug.LogWarning(pathModel.filePath + " no framework"); } } }
//添加其他资源 private static void AddOtherFile(string secondFilePath, string xcodeTargetPath, string xcodeTargetGuid, MOBPathModel pathModel, PBXProject xcodeProj, Hashtable fileFlags) { string[] secondDirectories = Directory.GetFiles(secondFilePath, "*", SearchOption.AllDirectories); foreach (string lastFilePath in secondDirectories) { if ((secondFilePath.EndsWith("SDK/ShareSDK") || secondFilePath.EndsWith("SDK\\ShareSDK")) && (lastFilePath.Contains("Support/PlatformSDK") || lastFilePath.Contains("Support\\PlatformSDK"))) { continue; } // Debug.LogWarning("lastFilePath:" + lastFilePath); if (!lastFilePath.Contains(".framework") && !lastFilePath.Contains(".a") && !lastFilePath.Contains(".h") && !lastFilePath.Contains(".bundle") && !lastFilePath.Contains(".DS_Store") && !lastFilePath.Contains(".meta")) { string otherFilePath = lastFilePath.Replace(pathModel.rootPath, ""); int index = otherFilePath.LastIndexOf("\\"); int fileNameIndex = 2; if (index == -1) { fileNameIndex = 1; index = otherFilePath.LastIndexOf("/"); } //项目目录 string saveOtherFilePath = otherFilePath.Substring(0, index); string fileName = otherFilePath.Substring(index + fileNameIndex); //存放的本地目录 string saveDirectory = xcodeTargetPath + saveOtherFilePath; if (!Directory.Exists(saveDirectory)) { Directory.CreateDirectory(saveDirectory); } //将其他文件拷贝到指定目录 FileInfo fileInfo = new FileInfo(lastFilePath); string savePath = xcodeTargetPath + otherFilePath; fileInfo.CopyTo(savePath, true); //将.a 加入 proj中 if (fileFlags.ContainsKey(fileName)) { string flag = (string)fileFlags[fileName]; //Debug.Log(flag); xcodeProj.AddFileToBuildWithFlags(xcodeTargetGuid, xcodeProj.AddFile(otherFilePath.Substring(1), "MOB" + otherFilePath, PBXSourceTree.Absolute), flag); } else { xcodeProj.AddFileToBuildSection(xcodeTargetGuid, xcodeProj.AddFrameworksBuildPhase(xcodeTargetGuid), xcodeProj.AddFile(otherFilePath.Substring(1), "MOB" + otherFilePath, PBXSourceTree.Absolute)); } } } }
public void AddBuildPhasesOutputIsExpected() { ResetGuidGenerator(); PBXProject proj = ReadPBXProject(); string target = proj.AddTarget("TestTarget", ".dylib", "test.type"); proj.AddSourcesBuildPhase(target); proj.AddResourcesBuildPhase(target); proj.AddFrameworksBuildPhase(target); proj.AddCopyFilesBuildPhase(target, "Copy resources", "$(DST_PATH)", "13"); TestOutput(proj, "add_build_phases1.pbxproj"); }
public void AddBuildPhasesReturnsExistingBuildPhase() { ResetGuidGenerator(); PBXProject proj = ReadPBXProject(); string target = proj.AddTarget("TestTarget", ".dylib", "test.type"); Assert.IsNull(proj.GetSourcesBuildPhaseByTarget(target)); Assert.AreEqual("CCCCCCCC0000000000000005", proj.AddSourcesBuildPhase(target)); Assert.AreEqual("CCCCCCCC0000000000000005", proj.GetSourcesBuildPhaseByTarget(target)); Assert.AreEqual("CCCCCCCC0000000000000005", proj.AddSourcesBuildPhase(target)); Assert.IsNull(proj.GetResourcesBuildPhaseByTarget(target)); Assert.AreEqual("CCCCCCCC0000000000000006", proj.AddResourcesBuildPhase(target)); Assert.AreEqual("CCCCCCCC0000000000000006", proj.GetResourcesBuildPhaseByTarget(target)); Assert.AreEqual("CCCCCCCC0000000000000006", proj.AddResourcesBuildPhase(target)); Assert.IsNull(proj.GetFrameworksBuildPhaseByTarget(target)); Assert.AreEqual("CCCCCCCC0000000000000007", proj.AddFrameworksBuildPhase(target)); Assert.AreEqual("CCCCCCCC0000000000000007", proj.GetFrameworksBuildPhaseByTarget(target)); Assert.AreEqual("CCCCCCCC0000000000000007", proj.AddFrameworksBuildPhase(target)); Assert.IsNull(proj.GetCopyFilesBuildPhaseByTarget(target, "Copy files", "", "13")); Assert.AreEqual("CCCCCCCC0000000000000008", proj.AddCopyFilesBuildPhase(target, "Copy files", "", "13")); Assert.AreEqual("CCCCCCCC0000000000000008", proj.GetCopyFilesBuildPhaseByTarget(target, "Copy files", "", "13")); Assert.AreEqual("CCCCCCCC0000000000000008", proj.AddCopyFilesBuildPhase(target, "Copy files", "", "13")); // check whether all parameters are actually matched against existing phases Assert.IsNull(proj.GetCopyFilesBuildPhaseByTarget(target, "Copy files2", "", "13")); Assert.IsNull(proj.GetCopyFilesBuildPhaseByTarget(target, "Copy files", "path", "13")); Assert.IsNull(proj.GetCopyFilesBuildPhaseByTarget(target, "Copy files", "", "14")); Assert.AreEqual("CCCCCCCC0000000000000009", proj.AddCopyFilesBuildPhase(target, "Copy files2", "", "13")); Assert.AreEqual("CCCCCCCC0000000000000009", proj.GetCopyFilesBuildPhaseByTarget(target, "Copy files2", "", "13")); Assert.AreEqual("CCCCCCCC0000000000000010", proj.AddCopyFilesBuildPhase(target, "Copy files", "path", "13")); Assert.AreEqual("CCCCCCCC0000000000000010", proj.GetCopyFilesBuildPhaseByTarget(target, "Copy files", "path", "13")); Assert.AreEqual("CCCCCCCC0000000000000011", proj.AddCopyFilesBuildPhase(target, "Copy files", "", "14")); Assert.AreEqual("CCCCCCCC0000000000000011", proj.GetCopyFilesBuildPhaseByTarget(target, "Copy files", "", "14")); }
//添加 .a文件 private static void AddStaticLibrary(string secondFilePath, string xcodeTargetPath, string xcodeTargetGuid, MOBPathModel pathModel, PBXProject xcodeProj) { // SearchOption searchOption; // if (secondFilePath.Contains ("/ShareSDK/")) //shareSDK // { // searchOption = SearchOption.TopDirectoryOnly; // } // else // { // searchOption = SearchOption.AllDirectories; // } string[] secondDirectories = Directory.GetFiles(secondFilePath, "*.a", SearchOption.AllDirectories); foreach (string lastFilePath in secondDirectories) { if ((secondFilePath.EndsWith("SDK/ShareSDK") || secondFilePath.EndsWith("SDK\\ShareSDK")) && (lastFilePath.Contains("Support/PlatformSDK") || lastFilePath.Contains("Support\\PlatformSDK"))) { continue; } string staticLibraryPath = lastFilePath.Replace(pathModel.rootPath, ""); int index = staticLibraryPath.LastIndexOf("\\"); if (index == -1) { index = staticLibraryPath.LastIndexOf("/"); } //项目目录 string saveStaticLibraryPath = staticLibraryPath.Substring(0, index); //存放的本地目录 string saveDirectory = xcodeTargetPath + saveStaticLibraryPath; if (!Directory.Exists(saveDirectory)) { Directory.CreateDirectory(saveDirectory); } //将.a copy到指定目录 FileInfo fileInfo = new FileInfo(lastFilePath); string savePath = xcodeTargetPath + staticLibraryPath; fileInfo.CopyTo(savePath, true); //将.a 加入 proj中 xcodeProj.AddFileToBuildSection(xcodeTargetGuid, xcodeProj.AddFrameworksBuildPhase(xcodeTargetGuid), xcodeProj.AddFile(staticLibraryPath.Substring(1), "MOB" + staticLibraryPath, PBXSourceTree.Absolute)); //将 build setting 设置 xcodeProj.AddBuildProperty(xcodeTargetGuid, "LIBRARY_SEARCH_PATHS", "$(SRCROOT)" + saveStaticLibraryPath.Replace("\\", "/")); } }
public static void ModifyProj(string path) { string projPath = PBXProject.GetPBXProjectPath(path); PBXProject pbxProj = new PBXProject(); pbxProj.ReadFromString(File.ReadAllText(projPath)); // 配置目标 string targetGuid = pbxProj.TargetGuidByName("Unity-iPhone"); // 关闭bitcode pbxProj.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "false"); // 添加.tbd pbxProj.AddFileToBuild(targetGuid, pbxProj.AddFile("usr/lib/libz.tbd", "Frameworks/libz.tbd", PBXSourceTree.Sdk)); pbxProj.AddFileToBuild(targetGuid, pbxProj.AddFile("usr/lib/libc++.tbd", "Frameworks/libc++.tbd", PBXSourceTree.Sdk)); pbxProj.AddFileToBuild(targetGuid, pbxProj.AddFile("usr/lib/Libicucore.tbd", "Frameworks/Libicucore.tbd", PBXSourceTree.Sdk)); // 添加系统内置框架 pbxProj.AddFrameworkToProject(targetGuid, "AVFoundation.framework", false); pbxProj.AddFrameworkToProject(targetGuid, "SystemConfiguration.framework", false); pbxProj.AddFrameworkToProject(targetGuid, "Foundation.framework", false); pbxProj.AddFrameworkToProject(targetGuid, "CoreTelephony.framework", false); pbxProj.AddFrameworkToProject(targetGuid, "AudioToolbox.framework", false); pbxProj.AddFrameworkToProject(targetGuid, "UIKit.framework", false); pbxProj.AddFrameworkToProject(targetGuid, "CoreLocation.framework", false); pbxProj.AddFrameworkToProject(targetGuid, "Contacts.framework", false); pbxProj.AddFrameworkToProject(targetGuid, "AddressBook.framework", false); pbxProj.AddFrameworkToProject(targetGuid, "QuartzCore.framework", false); pbxProj.AddFrameworkToProject(targetGuid, "CoreGraphics.framework", false); pbxProj.AddFrameworksBuildPhase(targetGuid); // 设置teamID //.. File.WriteAllText(projPath, pbxProj.WriteToString()); }
public void RemoveFrameworkWorks() { ResetGuidGenerator(); PBXProject proj = ReadPBXProject(); string targetGuid = proj.TargetGuidByName(PBXProject.GetUnityTargetName()); string target2Guid = proj.AddTarget("Other", "app", "com.apple.product-type.bundle"); proj.AddFrameworksBuildPhase(target2Guid); proj.AddFrameworkToProject(targetGuid, "GameCenter.framework", false); proj.AddFrameworkToProject(target2Guid, "GameCenter.framework", false); Assert.IsTrue(proj.ContainsFramework(targetGuid, "GameCenter.framework")); Assert.IsTrue(proj.ContainsFramework(target2Guid, "GameCenter.framework")); proj = Reserialize(proj); proj.RemoveFrameworkFromProject(targetGuid, "GameCenter.framework"); Assert.IsFalse(proj.ContainsFramework(targetGuid, "GameCenter.framework")); Assert.IsTrue(proj.ContainsFramework(target2Guid, "GameCenter.framework")); proj = Reserialize(proj); proj.RemoveFrameworkFromProject(target2Guid, "GameCenter.framework"); Assert.IsFalse(proj.ContainsFramework(targetGuid, "GameCenter.framework")); Assert.IsFalse(proj.ContainsFramework(target2Guid, "GameCenter.framework")); }
//添加 Framework private static void AddFramework(string secondFilePath, string xcodeTargetPath, string xcodeTargetGuid, string xcodeFrameworkTargetGuid, MOBPathModel pathModel, PBXProject xcodeProj, ref bool hasMobFramework, MOBXCodeEditorModel editModel) { SearchOption searchOption; if (secondFilePath.Contains("/ShareSDK/") || secondFilePath.Contains("\\ShareSDK\\") || secondFilePath.Contains("/ShareSDK\\")) //shareSDK { searchOption = SearchOption.TopDirectoryOnly; } else { searchOption = SearchOption.AllDirectories; } string[] secondDirectories = Directory.GetDirectories(secondFilePath, "*.framework", searchOption); foreach (string lastFilePath in secondDirectories) { // Debug.Log("lastFilePath" + lastFilePath); int index = lastFilePath.LastIndexOf("\\"); int fileNameIndex = 2; if (index == -1) { fileNameIndex = 1; index = lastFilePath.LastIndexOf("/"); } //framework 名称 string frameworkName = lastFilePath.Substring(index + fileNameIndex); // Debug.Log("frameworkName" + frameworkName); bool isMOBFoundation = (frameworkName == "MOBFoundation.framework"); if (!isMOBFoundation || (isMOBFoundation && !hasMobFramework)) { if (isMOBFoundation && !hasMobFramework) { // Debug.Log("isMOBFoundation " + lastFilePath); hasMobFramework = true; } string frameworkPath = lastFilePath.Replace(pathModel.rootPath, ""); // Debug.Log("frameworkPath" + frameworkPath); string savePath = xcodeTargetPath + frameworkPath; int tempIndex = frameworkPath.LastIndexOf("\\"); if (tempIndex == -1) { tempIndex = frameworkPath.LastIndexOf("/"); } string saveFrameworkPath = frameworkPath.Substring(0, tempIndex); string targetGuid = xcodeFrameworkTargetGuid; //将 framework copy到指定目录AddURLSchemes DirectoryInfo frameworkInfo = new DirectoryInfo(lastFilePath); DirectoryInfo saveFrameworkInfo = new DirectoryInfo(savePath); CopyAll(frameworkInfo, saveFrameworkInfo); //将 framework 加入 proj中 if (frameworkName == "ShareSDKLink.framework" && !editModel.isOpenRestoreScene) { continue; } string fileGuid = (string)xcodeProj.AddFile(frameworkPath.Substring(1), "MOB" + frameworkPath, PBXSourceTree.Absolute); string[] dynamicframework = { "OasisSDK.framework", "SCSDKCreativeKit.framework", "SCSDKLoginKit.framework", "SCSDKCoreKit.framework" }; int dynamicIndex = Array.IndexOf(dynamicframework, frameworkName); if (dynamicIndex >= 0) { targetGuid = xcodeTargetGuid; xcodeProj.AddFileToBuildSection(targetGuid, xcodeProj.AddFrameworksBuildPhase(targetGuid), fileGuid); #if UNITY_2019_3_OR_NEWER xcodeProj.AddFileToEmbedFrameworks(targetGuid, fileGuid, targetGuid); #endif } else { xcodeProj.AddFileToBuildSection(targetGuid, xcodeProj.AddFrameworksBuildPhase(targetGuid), fileGuid); } //将 build setting 设置 xcodeProj.AddBuildProperty(targetGuid, "FRAMEWORK_SEARCH_PATHS", "$(SRCROOT)" + saveFrameworkPath.Replace("\\", "/")); } } }