public void AddEmbedFrameworkWorks() { ResetGuidGenerator(); PBXProject proj = ReadPBXProject(); string target = proj.TargetGuidByName(PBXProject.GetUnityTargetName()); // first, include a framework as a regular file var fileGuid = proj.AddFile("path/test.framework", "Frameworks/test.framework"); Assert.AreEqual("CCCCCCCC0000000000000001", fileGuid); proj.AddFileToEmbedFrameworks(target, fileGuid); Assert.IsNotNull(proj.GetCopyFilesBuildPhaseByTarget(target, "Embed Frameworks", "", "10")); proj = Reserialize(proj); var buildFile = proj.BuildFilesGetForSourceFile(target, fileGuid); Assert.IsNotNull(buildFile); Assert.IsTrue(buildFile.codeSignOnCopy); Assert.IsTrue(buildFile.removeHeadersOnCopy); var copyPhaseGuid = proj.GetCopyFilesBuildPhaseByTarget(target, "Embed Frameworks", "", "10"); Assert.IsTrue(proj.copyFiles[copyPhaseGuid].files.Contains(buildFile.guid)); }
private static void PrepareProject(string buildPath) { var projPath = Path.Combine(buildPath, "Unity-iPhone.xcodeproj/project.pbxproj"); var project = new PBXProject(); project.ReadFromString(File.ReadAllText(projPath)); var target = project.TargetGuidByName("Unity-iPhone"); foreach (var lib in PlatformLibs) { string libGUID = project.AddFile("usr/lib/" + lib, "Libraries/" + lib, PBXSourceTree.Sdk); project.AddFileToBuild(target, libGUID); } var fileGuid = project.FindFileGuidByProjectPath("Frameworks/Plugins/iOS/MoPubSDKFramework.framework"); #if UNITY_2017_1_OR_NEWER project.AddFileToEmbedFrameworks(target, fileGuid); #endif project.SetBuildProperty( target, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks"); project.AddBuildProperty(target, "OTHER_LDFLAGS", "-ObjC"); project.AddBuildProperty(target, "GCC_ENABLE_OBJC_EXCEPTIONS", "YES"); project.AddBuildProperty(target, "CLANG_ENABLE_MODULES", "YES"); project.AddBuildProperty(target, "ENABLE_BITCODE", "NO"); File.WriteAllText(projPath, project.WriteToString()); }
private static void AddFileToEmbedFrameworks(PBXProject project, string target, string unityPath, string xcodePath) { string frameworkPath = project.AddFile(unityPath, xcodePath, PBXSourceTree.Source); project.AddFileToBuild(target, frameworkPath); project.AddFileToEmbedFrameworks(target, frameworkPath); }
public static void LinkLibraries(string path) { // linked library string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj"; PBXProject proj = new PBXProject(); proj.ReadFromFile(projPath); string target = GetTargetGuid(proj); // disable bit-code proj.SetBuildProperty(target, "ENABLE_BITCODE", "false"); // Frameworks foreach (string framework in ProjectFrameworks) { proj.AddFrameworkToProject(target, framework, true); } // embedded frameworks #if UNITY_2019_1_OR_NEWER target = proj.GetUnityMainTargetGuid(); #endif const string defaultLocationInProj = "Frameworks/AgoraEngine/Plugins/iOS"; const string rtcFrameworkName = "AgoraRtcKit.framework"; const string cryptoFrameworkName = "AgoraRtcCryptoLoader.framework"; string fw1 = Path.Combine(defaultLocationInProj, rtcFrameworkName); string fw2 = Path.Combine(defaultLocationInProj, cryptoFrameworkName); string fileGuid = proj.AddFile(fw1, fw1, PBXSourceTree.Source); proj.AddFileToEmbedFrameworks(target, fileGuid); fileGuid = proj.AddFile(fw2, fw2, PBXSourceTree.Source); proj.AddFileToEmbedFrameworks(target, fileGuid); proj.SetBuildProperty(target, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks"); // done, write to the project file File.WriteAllText(projPath, proj.WriteToString()); // permission string pListPath = path + "/Info.plist"; PlistDocument plist = new PlistDocument(); plist.ReadFromString(File.ReadAllText(pListPath)); PlistElementDict rootDic = plist.root; var micPermission = "NSMicrophoneUsageDescription"; rootDic.SetString(micPermission, "Voice call need to user mic"); File.WriteAllText(pListPath, plist.WriteToString()); }
public static void IosXcodeFix(string path) { PBXProject project = new PBXProject(); string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj"; project.ReadFromString(File.ReadAllText(projPath)); string target = project.TargetGuidByName("Unity-iPhone"); Debug.Log("Setting linker flag ENABLE_BITCODE to NO"); project.SetBuildProperty(target, "ENABLE_BITCODE", "NO"); //get the framework file id (check for possible different locations) string fileId = null; //universal (new) if (fileId == null) { fileId = project.FindFileGuidByProjectPath("Frameworks/WebRtcVideoChat/Plugins/ios/universal/webrtccsharpwrap.framework"); } //armv7 only if (fileId == null) { fileId = project.FindFileGuidByProjectPath("Frameworks/WebRtcVideoChat/Plugins/ios/armv7/webrtccsharpwrap.framework"); } //arm64 only if (fileId == null) { fileId = project.FindFileGuidByProjectPath("Frameworks/WebRtcVideoChat/Plugins/ios/arm64/webrtccsharpwrap.framework"); } //manual placement if (fileId == null) { fileId = project.FindFileGuidByProjectPath("Frameworks/webrtccsharpwrap.framework"); } Debug.Log("Adding build phase CopyFrameworks to copy the framework to the app Frameworks directory"); #if UNITY_2017_2_OR_NEWER project.AddFileToEmbedFrameworks(target, fileId); #else string copyFilePhase = project.AddCopyFilesBuildPhase(target, "CopyFrameworks", "", "10"); project.AddFileToBuildSection(target, copyFilePhase, fileId); //Couldn't figure out how to set that flag yet. Debug.LogWarning("Code Sign On Copy flag must be set manually via Xcode for webrtccsharpwrap.framework:" + "Project settings -> Build phases -> Copy Frameworks -> set the flag Code Sign On Copy"); #endif //make sure the Framework is expected in the Frameworks path. Without that ios won't find the framework project.AddBuildProperty(target, "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks"); File.WriteAllText(projPath, project.WriteToString()); }
public static void MaxPostProcessEmbedDynamicLibraries(BuildTarget buildTarget, string path) { var dynamicLibraryPathsPresentInProject = DynamicLibraryPathsToEmbed.Where(dynamicLibraryPath => Directory.Exists(Path.Combine(path, dynamicLibraryPath))).ToList(); if (dynamicLibraryPathsPresentInProject.Count <= 0) { return; } var projectPath = PBXProject.GetPBXProjectPath(path); var project = new PBXProject(); project.ReadFromFile(projectPath); #if UNITY_2019_3_OR_NEWER var targetGuid = project.GetUnityMainTargetGuid(); var containsUnityiPhoneTargetInPodfile = ContainsUnityiPhoneTargetInPodfile(path); // Embed framework if it is .xcframework or is .framework and the podfile does not contain target `Unity-iPhone`. foreach (var dynamicLibraryPath in dynamicLibraryPathsPresentInProject) { if (dynamicLibraryPath.EndsWith(".framework") && containsUnityiPhoneTargetInPodfile) { continue; } var fileGuid = project.AddFile(dynamicLibraryPath, dynamicLibraryPath); project.AddFileToEmbedFrameworks(targetGuid, fileGuid); } #else var targetGuid = project.TargetGuidByName("Unity-iPhone"); string runpathSearchPaths; #if UNITY_2018_2_OR_NEWER runpathSearchPaths = project.GetBuildPropertyForAnyConfig(targetGuid, "LD_RUNPATH_SEARCH_PATHS"); #else runpathSearchPaths = "$(inherited)"; #endif runpathSearchPaths += string.IsNullOrEmpty(runpathSearchPaths) ? "" : " "; // Check if runtime search paths already contains the required search paths for dynamic libraries. if (runpathSearchPaths.Contains("@executable_path/Frameworks")) { return; } runpathSearchPaths += "@executable_path/Frameworks"; project.SetBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", runpathSearchPaths); #endif if (ShouldEmbedSnapSdk()) { // Needed to build successfully on Xcode 12+, as Snap was build with latest Xcode but not as an xcframework project.AddBuildProperty(targetGuid, "VALIDATE_WORKSPACE", "YES"); } project.WriteToFile(projectPath); }
private static void AddEmbeddedFrameworks(PBXProject proj, string targetGuid) { foreach (var framework in ISD_Settings.Instance.EmbededFrameworks) { var fileGuid = proj.AddFile(framework.AbsoluteFilePath, "Frameworks/" + framework.FileName, PBXSourceTree.Source); var embedPhase = proj.AddCopyFilesBuildPhase(targetGuid, "Embed Frameworks", "", "10"); proj.AddFileToBuildSection(targetGuid, embedPhase, fileGuid); #if UNITY_2017_4_OR_NEWER proj.AddFileToEmbedFrameworks(targetGuid, fileGuid); #endif proj.AddBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks"); } }
static void LinkLibraries(string path) { // linked library string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj"; PBXProject proj = new PBXProject(); proj.ReadFromFile(projPath); string target = GetTargetGuid(proj); // disable bit-code proj.SetBuildProperty(target, "ENABLE_BITCODE", "false"); // Frameworks foreach (string framework in ProjectFrameworks) { proj.AddFrameworkToProject(target, framework, true); } // embedded frameworks #if UNITY_2019_1_OR_NEWER target = proj.GetUnityMainTargetGuid(); #endif const string defaultLocationInProj = "Frameworks/AgoraEngine/Plugins/iOS"; const string rtcFrameworkName = "AgoraRtcKit.framework"; const string cryptoFrameworkName = "AgoraRtcCryptoLoader.framework"; string fw1 = Path.Combine(defaultLocationInProj, rtcFrameworkName); string fw2 = Path.Combine(defaultLocationInProj, cryptoFrameworkName); string fileGuid = proj.AddFile(fw1, fw1, PBXSourceTree.Source); proj.AddFileToEmbedFrameworks(target, fileGuid); fileGuid = proj.AddFile(fw2, fw2, PBXSourceTree.Source); proj.AddFileToEmbedFrameworks(target, fileGuid); proj.SetBuildProperty(target, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks"); // done, write to the project file File.WriteAllText(projPath, proj.WriteToString()); }
public static void OnPostprocessBuild(BuildTarget buildTarget, string path) { if (buildTarget == BuildTarget.iOS) { #if UNITY_5_0 || UNITY_5_1 || UNITY5_2 string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj"; #else string projPath = PBXProject.GetPBXProjectPath(path); #endif PBXProject proj = new PBXProject(); proj.ReadFromString(System.IO.File.ReadAllText(projPath)); #if UNITY_5_0 || UNITY_5_1 || UNITY5_2 string target = proj.TargetGuidByName("Unity-iPhone"); #else string target = proj.TargetGuidByName(PBXProject.GetUnityTargetName()); #endif #if UNITY_2017_2_OR_NEWER string frameworkPath = "Frameworks/OpenCVForUnity/Plugins/iOS/opencv2.framework"; string fileGuid = proj.FindFileGuidByProjectPath(frameworkPath); proj.AddFileToBuild(target, fileGuid); proj.AddFileToEmbedFrameworks(target, fileGuid); foreach (var configName in proj.BuildConfigNames()) { var configGuid = proj.BuildConfigByName(target, configName); proj.SetBuildPropertyForConfig(configGuid, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks"); } #else Debug.LogError("If the version of Unity is less than 2017.2, you have to set opencv2.framework to Embedded Binaries manually."); #endif File.WriteAllText(projPath, proj.WriteToString()); #if UNITY_5_5_OR_NEWER if ((int)Convert.ToDecimal(PlayerSettings.iOS.targetOSVersionString) < 8) { #else if ((int)PlayerSettings.iOS.targetOSVersion < (int)iOSTargetOSVersion.iOS_8_0) { #endif Debug.LogError("Please set Target minimum iOS Version to 8.0 or higher."); } } } }
private static void PrepareProject(string buildPath) { var projPath = Path.Combine(buildPath, "Unity-iPhone.xcodeproj/project.pbxproj"); var project = new PBXProject(); project.ReadFromString(File.ReadAllText(projPath)); var target = project.TargetGuidByName("Unity-iPhone"); foreach (var lib in PlatformLibs) { string libGUID = project.AddFile("usr/lib/" + lib, "Libraries/" + lib, PBXSourceTree.Sdk); project.AddFileToBuild(target, libGUID); } bool emitWarning = true; #if UNITY_2017_1_OR_NEWER var fileGuid = project.FindFileGuidByProjectPath("Frameworks/MoPub/Plugins/iOS/MoPubSDKFramework.framework") // Unity 2018.3 leaves out the intermediate directories. ?? project.FindFileGuidByProjectPath("Frameworks/MoPubSDKFramework.framework") // Check legacy location in case post 5.4 file migration has not been done. ?? project.FindFileGuidByProjectPath("Frameworks/Plugins/iOS/MoPubSDKFramework.framework"); if (fileGuid != null) { project.AddFileToEmbedFrameworks(target, fileGuid); emitWarning = false; } #endif if (emitWarning) { Debug.LogWarning( "Unable to automatically add MoPubSDKFramework.framework to the Embedded Binaries list in the Xcode project.\n" + "Please add it manually in Xcode, under the General properties of the Unity-iPhone target, unless you\n" + "are building against the SDK source (via Cocoapods) or static library."); } project.SetBuildProperty( target, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks"); project.AddBuildProperty(target, "OTHER_LDFLAGS", "-ObjC"); project.AddBuildProperty(target, "GCC_ENABLE_OBJC_EXCEPTIONS", "YES"); project.AddBuildProperty(target, "CLANG_ENABLE_MODULES", "YES"); project.AddBuildProperty(target, "ENABLE_BITCODE", "NO"); File.WriteAllText(projPath, project.WriteToString()); }
private static void EmbedDynamicLibrariesIfNeeded(string buildPath, PBXProject project, string targetGuid) { var dynamicLibraryPathsPresentInProject = DynamicLibraryPathsToEmbed.Where(dynamicLibraryPath => Directory.Exists(Path.Combine(buildPath, dynamicLibraryPath))).ToList(); if (dynamicLibraryPathsPresentInProject.Count <= 0) { return; } #if UNITY_2019_3_OR_NEWER // Embed framework only if the podfile does not contain target `Unity-iPhone`. if (!ContainsUnityIphoneTargetInPodfile(buildPath)) { foreach (var dynamicLibraryPath in dynamicLibraryPathsPresentInProject) { var fileGuid = project.AddFile(dynamicLibraryPath, dynamicLibraryPath); project.AddFileToEmbedFrameworks(targetGuid, fileGuid); } } #else string runpathSearchPaths; #if UNITY_2018_2_OR_NEWER runpathSearchPaths = project.GetBuildPropertyForAnyConfig(targetGuid, "LD_RUNPATH_SEARCH_PATHS"); #else runpathSearchPaths = "$(inherited)"; #endif runpathSearchPaths += string.IsNullOrEmpty(runpathSearchPaths) ? "" : " "; // Check if runtime search paths already contains the required search paths for dynamic libraries. if (runpathSearchPaths.Contains("@executable_path/Frameworks")) { return; } runpathSearchPaths += "@executable_path/Frameworks"; project.SetBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", runpathSearchPaths); #endif if (ShouldEmbedSnapSdk()) { // Needed to build successfully on Xcode 12+, as Snap was build with latest Xcode but not as an xcframework project.AddBuildProperty(targetGuid, "VALIDATE_WORKSPACE", "YES"); } }
public static void MaxPostProcessEmbedDynamicLibraries(BuildTarget buildTarget, string path) { var dynamicLibraryPathsPresentInProject = DynamicLibraryPathsToEmbed.Where(dynamicLibraryPath => Directory.Exists(Path.Combine(path, dynamicLibraryPath))).ToList(); if (dynamicLibraryPathsPresentInProject.Count <= 0) { return; } var projectPath = PBXProject.GetPBXProjectPath(path); var project = new PBXProject(); project.ReadFromFile(projectPath); #if UNITY_2019_3_OR_NEWER var targetGuid = project.GetUnityMainTargetGuid(); foreach (var dynamicLibraryPath in dynamicLibraryPathsPresentInProject) { var fileGuid = project.AddFile(dynamicLibraryPath, dynamicLibraryPath); project.AddFileToEmbedFrameworks(targetGuid, fileGuid); } #else var targetGuid = project.TargetGuidByName("Unity-iPhone"); string runpathSearchPaths; #if UNITY_2018_2_OR_NEWER runpathSearchPaths = project.GetBuildPropertyForAnyConfig(targetGuid, "LD_RUNPATH_SEARCH_PATHS"); #else runpathSearchPaths = "$(inherited)"; #endif runpathSearchPaths += string.IsNullOrEmpty(runpathSearchPaths) ? "" : " "; // Check if runtime search paths already contains the required search paths for dynamic libraries. if (runpathSearchPaths.Contains("@executable_path/Frameworks")) { return; } runpathSearchPaths += "@executable_path/Frameworks"; project.SetBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", runpathSearchPaths); #endif project.WriteToFile(projectPath); }
private static void AddFrameworksToProject(PBXProject pbx, string pathToSrcProject) { var targetGuid = pbx.TargetGuidByName(Build.XCTargetName); var srcPath = Path.Combine(pathToSrcProject, "Frameworks"); var dstPath = Path.Combine(Build.XCTargetName, "Unity", Path.GetFileName(pathToSrcProject), "Frameworks"); foreach (var frameworkPath in Directory.GetDirectories(srcPath, "*.framework")) { var frameworkName = Path.GetFileName(frameworkPath); if (!pbx.ContainsFramework(targetGuid, frameworkName)) { var relativePath = Path.Combine("..", frameworkPath.Remove(0, pathToSrcProject.LastIndexOf("Unity", StringComparison.OrdinalIgnoreCase))); var frameworkGuid = pbx.AddFile(relativePath, Path.Combine(dstPath, frameworkName), PBXSourceTree.Source); pbx.AddFileToEmbedFrameworks(targetGuid, frameworkGuid); } } }
private static void EmbedDynamicLibrariesIfNeeded(string buildPath, PBXProject project, string targetGuid, DependencyManager deps) { for (int i = 0; i < deps.networks.Length; i++) { var dynamicLibraryPath = deps.networks[i].embedFramework; if (string.IsNullOrEmpty(dynamicLibraryPath)) { continue; } dynamicLibraryPath = Path.Combine("Pods", dynamicLibraryPath); if (!Directory.Exists(Path.Combine(buildPath, dynamicLibraryPath))) { continue; } #if UNITY_2019_3_OR_NEWER var fileGuid = project.AddFile(dynamicLibraryPath, dynamicLibraryPath); project.AddFileToEmbedFrameworks(targetGuid, fileGuid); #endif } }
public static void OnPostprocessBuild(BuildTarget buildTarget, string path) { if (buildTarget == BuildTarget.iOS) { string pbxProjectPath = PBXProject.GetPBXProjectPath(path); PBXProject pbxProject = new PBXProject(); pbxProject.ReadFromString(File.ReadAllText(pbxProjectPath)); #if UNITY_2019_3_OR_NEWER string targetGuid = pbxProject.GetUnityMainTargetGuid(); #else string targetGuid = pbxProject.TargetGuidByName("Unity-iPhone"); #endif // Framework Embed const string relativeFrameworkFolder = "Library/Oqupie/SDK/iOS"; const string frameworkName = "OqupieSupportSDK.framework"; string frameworkPath = Path.Combine(relativeFrameworkFolder, frameworkName); string fileGuid = pbxProject.AddFile(frameworkPath, "Frameworks/" + frameworkPath, PBXSourceTree.Sdk); pbxProject.AddFileToEmbedFrameworks(targetGuid, fileGuid); pbxProject.SetBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks"); // PBXProject 저장 pbxProject.WriteToFile(pbxProjectPath); // plist 수정 string plistPath = path + "/Info.plist"; PlistDocument plist = new PlistDocument(); plist.ReadFromString(File.ReadAllText(plistPath)); PlistElementDict rootDict = plist.root; // Privacy - Photo Library Usage Description rootDict.SetString("NSPhotoLibraryUsageDescription", "This app needs to use photo library for file attachment"); // Privacy - Camera Usage Description rootDict.SetString("NSCameraUsageDescription", "This app needs to use camera for file attachment"); // plist 저장 File.WriteAllText(plistPath, plist.WriteToString()); } }
public static void OnPostProcessBuild(BuildTarget buildTarget, string path) { if (buildTarget == BuildTarget.iOS) { var projPath = PBXProject.GetPBXProjectPath(path); var proj = new PBXProject(); proj.ReadFromFile(projPath); var target = proj.TargetGuidByName(PBXProject.GetUnityTargetName()); // Other Linker Flagsに-ObjCを追加 proj.AddBuildProperty(target, "OTHER_LDFLAGS", "-ObjC"); // Linked Frameworks and Librariesにフレームワークを追加 proj.AddFrameworkToProject(target, "WebKit.framework", false); proj.AddFrameworkToProject(target, "GLKit.framework", false); proj.AddFrameworkToProject(target, "MessageUI.framework", false); proj.AddFrameworkToProject(target, "ImageIO.framework", false); proj.AddFrameworkToProject(target, "libz.tbd", false); proj.AddFrameworkToProject(target, "libxml2.tbd", false); proj.AddFrameworkToProject(target, "libc++.tbd", false); proj.AddFrameworkToProject(target, "libsqlite3.tbd", false); proj.AddFrameworkToProject(target, "CoreFoundation.framework", true); #region MoPubの設定 #if UNITY_2017_1_OR_NEWER var mopubFileGuid = proj.FindFileGuidByProjectPath("Frameworks/Plugins/iOS/sdk/MoPubSDKFramework.framework"); proj.AddFileToEmbedFrameworks(target, mopubFileGuid); #endif var maskedFiles = Directory.GetFiles( path, "*.prevent_unity_compilation", SearchOption.AllDirectories); foreach (var maskedFile in maskedFiles) { var unmaskedFile = maskedFile.Replace(".prevent_unity_compilation", ""); File.Move(maskedFile, unmaskedFile); } #endregion File.WriteAllText(projPath, proj.WriteToString()); } }
public static void OnPostProcessBuild(BuildTarget buildTarget, string buildPath) { if (buildTarget == BuildTarget.iOS) { Debug.Log("[AppLovin MAX] Starting iOS post-process build script..."); var projectPath = Path.Combine(buildPath, "Unity-iPhone.xcodeproj/project.pbxproj"); var project = new PBXProject(); project.ReadFromString(File.ReadAllText(projectPath)); // // Add the -ObjC linker flag // #if UNITY_2019_3_OR_NEWER var target = project.GetUnityMainTargetGuid(); #else var target = project.TargetGuidByName("Unity-iPhone"); #endif project.AddBuildProperty(target, "OTHER_LDFLAGS", "-ObjC"); // // Add needed frameworks to Embedded Libraries // string moPubFrameworkFileGuid = project.FindFileGuidByProjectPath("Frameworks/MaxSdk/Plugins/iOS/MoPub/MoPubSDKFramework.framework"); // The publisher might be using Unity 2018.3 which adds the frameworks directly into the `Frameworks/` directory. if (moPubFrameworkFileGuid == null) { moPubFrameworkFileGuid = project.FindFileGuidByProjectPath("Frameworks/MoPubSDKFramework.framework"); } if (moPubFrameworkFileGuid != null) { #if UNITY_2017_1_OR_NEWER Debug.Log("[AppLovin MAX] Adding MoPubSDKFramework.framework to Embedded Binaries list in the Xcode project"); project.AddFileToEmbedFrameworks(target, moPubFrameworkFileGuid); #else Debug.Log("[AppLovin Max] Failed to add MoPubSDKFramework.framework to Embedded Binaries. Please add it manually in your Xcode project."); #endif // Add `@executable_path/Frameworks` to Run Search Paths needed for embedded frameworks on older version of Unity. // NOTE: Unity automatically adds it for newer versions but we don't exactly know the version in which they started doing it, so we will be adding it to all versions. project.SetBuildProperty(target, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks"); } // // Write modified Xcode project back to original location // File.WriteAllText(projectPath, project.WriteToString()); Debug.Log("[AppLovin MAX] Finished iOS post-process build script..."); } // Rename files masked to prevent Unity compilation such as MoPub's mraid.js string[] noCompileFiles = Directory.GetFiles(buildPath, "*.no_compile", SearchOption.AllDirectories); foreach (var noCompileFile in noCompileFiles) { Debug.Log("[AppLovin MAX] Removing .no_compile mask from file: " + noCompileFile); File.Move(noCompileFile, noCompileFile.Replace(".no_compile", "")); } }
public static void OnPostprocessBuild(BuildTarget buildTarget, string pathToBuiltProject) { if (buildTarget != BuildTarget.iOS) { return; } Debug.Log("TAP PostProcessBuild projectPath = " + pathToBuiltProject); // Initialize PbxProject var projectPath = pathToBuiltProject + "/Unity-iPhone.xcodeproj/project.pbxproj"; PBXProject pbxProject = new PBXProject(); pbxProject.ReadFromFile(projectPath); string targetGuid = pbxProject.TargetGuidByName("Unity-iPhone"); Debug.Log("TAP PostProcessBuild pbxproject initialized"); pbxProject.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO"); pbxProject.SetBuildProperty(targetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES"); Debug.Log("TAP PostProcessBuild pbxproject set properties"); string unityBridgeFrameworkPath = "Frameworks/TAP/iOS/TAPKitUnityBridge.framework"; string guidTAPKitUnityBridge = pbxProject.FindFileGuidByProjectPath(unityBridgeFrameworkPath); if (guidTAPKitUnityBridge != null && guidTAPKitUnityBridge != "") { pbxProject.AddFileToEmbedFrameworks(targetGuid, guidTAPKitUnityBridge); } else { Debug.LogError("Error adding TAPKitUnityBridge to embed frameworks"); } //string unityBridgeFrameworkPath = "Frameworks/TAP/iOS/TAPKit.framework"; //string guidTAPKitUnityBridge = pbxProject.FindFileGuidByProjectPath(unityBridgeFrameworkPath); //if (guidTAPKitUnityBridge != null && guidTAPKitUnityBridge != "") //{ // pbxProject.AddFileToEmbedFrameworks(targetGuid, guidTAPKitUnityBridge); //} //else //{ // Debug.LogError("Error adding TAPKitUnityBridge to embed frameworks"); //} //string FrameworksPluginsPath = "Frameworks/TAP/iOS/"; /* * // Add embed frameworks : * string FrameworksPluginsPath = "Plugins/iOS/TAP"; * // string TAPKitFrameworkName = "TAPKit.framework"; * string TAPKitUnityBridgeFrameworkName = "TAPKitUnityBridge.framework"; * * * * * // string guidTAPKit = pbxProject.FindFileGuidByProjectPath ("Frameworks/" + FrameworksPluginsPath + "/" + TAPKitFrameworkName); * //string guidTAPKitUnityBridge = pbxProject.FindFileGuidByProjectPath ("Frameworks/" + FrameworksPluginsPath + "/" + TAPKitUnityBridgeFrameworkName); * string guidTAPKitUnityBridge = pbxProject.FindFileGuidByProjectPath ("Frameworks/" + FrameworksPluginsPath + "/" + TAPKitUnityBridgeFrameworkName); * * Debug.Log ("TAP PostProcessBuild TAPKitUnityBridge guid = " + guidTAPKitUnityBridge); * // if (guidTAPKit == "") { * // Debug.LogError (TAPKitFrameworkName + " Framework not found. make sure it's in the correct folder: " + FrameworksPluginsPath); * // } else * * if (guidTAPKitUnityBridge == null || (guidTAPKitUnityBridge != null && guidTAPKitUnityBridge == "")) { * Debug.LogError (TAPKitUnityBridgeFrameworkName + " Framework not found. make sure it's in the correct folder: " + FrameworksPluginsPath); * } else { * // pbxProject.AddFileToEmbedFrameworks (targetGuid, guidTAPKit); * pbxProject.AddFileToEmbedFrameworks (targetGuid, guidTAPKitUnityBridge); * Debug.Log ("TAP PostProcessBuild pbxproject Added embed frameworks"); * } */ File.WriteAllText(projectPath, pbxProject.WriteToString()); }
private void IOSPostProcess(string path) { var psIOS = Module.UserConfig.Json.PlayerSettings.IOS; //init string projPath = PBXProject.GetPBXProjectPath(path); PBXProject proj = new PBXProject(); proj.ReadFromString(File.ReadAllText(projPath)); string target = proj.TargetGuidByName("Unity-iPhone"); //customsetting //*******************************添加framework*******************************// proj.AddFrameworkToProject(target, "CoreLocation.framework", false); proj.AddFrameworkToProject(target, "UserNotifications.framework", false); proj.AddFrameworkToProject(target, "SystemConfiguration.framework", false); proj.AddFrameworkToProject(target, "Security.framework", false); proj.AddFrameworkToProject(target, "CoreTelephony.framework", false); proj.AddFrameworkToProject(target, "JavaScriptCore.framework", false); proj.AddFrameworkToProject(target, "MobileCoreServices.framework", false); proj.AddFrameworkToProject(target, "AVFoundation.framework", false); //*******************************添加tbd*******************************// proj.AddFileToBuild(target, proj.AddFile("usr/lib/libz.tbd", "Frameworks/libz.tbd", PBXSourceTree.Sdk)); proj.AddFileToBuild(target, proj.AddFile("usr/lib/libc++.tbd", "Frameworks/libc++.tbd", PBXSourceTree.Sdk)); proj.AddFileToBuild(target, proj.AddFile("usr/lib/libsqlite3.tbd", "Frameworks/libsqlite3.tbd", PBXSourceTree.Sdk)); //*******************************添加第三方framework*******************************// //CopyAndReplaceDirectory(psIOS.ThirdFrameWorkPath + "/BuglySDK/Bugly/Bugly.framework", Path.Combine(path, "Frameworks/Bugly.framework")); //proj.AddFileToBuild(target, proj.AddFile("Frameworks/Bugly.framework", "Frameworks/Bugly.framework", PBXSourceTree.Source)); // 追加framework的检索目录 proj.SetBuildProperty(target, "FRAMEWORK_SEARCH_PATHS", "$(inherited)"); proj.AddBuildProperty(target, "FRAMEWORK_SEARCH_PATHS", "$(PROJECT_DIR)/Frameworks/**"); //*******************************设置buildsetting*******************************// proj.SetBuildProperty(target, "ENABLE_BITCODE", "NO"); proj.AddBuildProperty(target, "OTHER_LDFLAGS", "-ObjC"); proj.SetBuildProperty(target, "BUILD_PRODUCTS_PATH", path); proj.SetBuildProperty(target, "DEBUG_INFORMATION_FORMAT", "DWARF with dSYM File"); proj.SetBuildProperty(target, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks");//如果没有这句话,运行会崩溃,报 image not found 错误 //*******************************设置EmbedFrameworks*******************************// string defaultLocationInProj = "Frameworks/Plugins/iOS"; string framework = Path.Combine(defaultLocationInProj, "GWebVideoUI.bundle"); string fileGuid = proj.AddFile(framework, "Frameworks/" + framework, PBXSourceTree.Sdk); proj.AddFileToEmbedFrameworks(target, fileGuid); framework = Path.Combine(defaultLocationInProj, "GWebVideo.framework"); fileGuid = proj.AddFile(framework, "Frameworks/" + framework, PBXSourceTree.Sdk); proj.AddFileToEmbedFrameworks(target, fileGuid); //*******************************设置plist文件*******************************// // XCPlist list = new XCPlist (xcodePath); // string blueToothAdd = @"<key>NSBluetoothPeripheralUsageDescription</key><string>" + BlueToothUsageDesc + @"</string>"; //添加蓝牙权限 // list.AddKey (blueToothAdd); // list.Save (); // XCPlist list2 = new XCPlist(xcodePath); // string photoAdd = @"<key>NSPhotoLibraryUsageDescription</key><string>" + PhotoUsageDesc + @"</string>"; //添加相机权限 // list2.AddKey(photoAdd); // list2.Save(); // XCPlist list3 = new XCPlist(xcodePath); // string photoAdd2 = @"<key>NSPhotoLibraryAddUsageDescription</key><string>" + PhotoUsageAddDesc + @"</string>"; //添加iOS11相机权限 // list3.AddKey(photoAdd2); // list3.Save(); string plistPath = Path.Combine(path, "info.plist"); var plist = new PlistDocument(); plist.ReadFromFile(plistPath); plist.root.SetString("NSBluetoothPeripheralUsageDescription", psIOS.BlueToothUsageDesc); plist.root.SetString("NSPhotoLibraryUsageDescription", psIOS.PhotoUsageDesc); plist.root.SetString("NSPhotoLibraryAddUsageDescription", psIOS.PhotoUsageAddDesc); PlistElementArray loginChannelsArr = plist.root.CreateArray("LSApplicationQueriesSchemes"); loginChannelsArr.AddString("mqqapi"); File.WriteAllText(plistPath, plist.WriteToString()); //*******************************编辑代码文件*******************************// //读取UnityAppController.mm文件 XClass UnityAppController = new XClass(path + "/Classes/UnityAppController.mm"); //在指定代码后面增加一行代码 UnityAppController.WriteBelow("#include \"PluginBase/AppDelegateListener.h\"", "#import <Bugly/Bugly.h>"); UnityAppController.WriteBelow("[KeyboardDelegate Initialize];", "[Bugly startWithAppId:@\"" + BuglyInit.BuglyAppID + "\"];"); File.WriteAllText(projPath, proj.WriteToString()); //*******************************Build Xcode*******************************// if (psIOS.IPAExportOptions.ExportIPA) { CreateIPAExportOptionsPlist(); XcodeBuild(); } }
//添加 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("\\", "/")); } } }
/// <summary> /// 指定ディレクトリをXcodeにコピーして追加する /// </summary> public static void CopyAndAddBuildToXcode( PBXProject pbxProject, string targetGuid, string copyDirectoryPath, string buildPath, string currentDirectoryPath, bool needToAddBuild = true ) { XcodeProjectSetting setting = Resources.Load <XcodeProjectSetting>(XcodeProjectUpdater.SETTING_DATA_PATH); HashSet <string> embedHash = new HashSet <string>(setting.EmbedFrameworks); //コピー元(Unity)のディレクトリとコピー先(Xcode)のディレクトリのパスを作成 string unityDirectoryPath = copyDirectoryPath; string xcodeDirectoryPath = buildPath; //ディレクトリ内のディレクトリの中身をコピーしている場合 if (!string.IsNullOrEmpty(currentDirectoryPath)) { unityDirectoryPath = Path.Combine(unityDirectoryPath, currentDirectoryPath); xcodeDirectoryPath = Path.Combine(xcodeDirectoryPath, currentDirectoryPath); //既にディクショナリーがある場合は削除し、新たにディクショナリー作成 Delete(xcodeDirectoryPath); Directory.CreateDirectory(xcodeDirectoryPath); } //ファイルをコピーし、プロジェクトへの追加も行う foreach (string filePath in Directory.GetFiles(unityDirectoryPath)) { //metaファイルはコピーしない string extension = Path.GetExtension(filePath); if (extension == ExtensionName.META) { continue; } //アーカイブファイルの場合は、それが入っているディレクトリにパスを通す else if (extension == ExtensionName.ARCHIVE) { pbxProject.AddBuildProperty( targetGuid, XcodeProjectSetting.LIBRARY_SEARCH_PATHS_KEY, XcodeProjectSetting.PROJECT_ROOT + currentDirectoryPath ); } //ファイルパスからファイル名を取得し、コピー先のパスを作成 string fileName = Path.GetFileName(filePath); string copyPath = Path.Combine(xcodeDirectoryPath, fileName); //隠しファイルはコピーしない .DS_Storeとか if (fileName[0] == '.') { continue; } //既に同名ファイルがある場合は削除、その後コピー File.Delete(copyPath); File.Copy(filePath, copyPath); if (needToAddBuild) { //プロジェクト内へ追加する時のパスは、ビルドしたディレクトリからの相対パス string relativePath = Path.Combine(currentDirectoryPath, fileName); pbxProject.AddFileToBuild(targetGuid, pbxProject.AddFile(relativePath, relativePath, PBXSourceTree.Source)); } } //ディレクトリの中にあるディレクトリの中もコピー foreach (string directoryPath in Directory.GetDirectories(unityDirectoryPath)) { string directoryName = Path.GetFileName(directoryPath); bool nextNeedToAddBuild = needToAddBuild; //フレームワークやImages.xcassetsがが入っているディレクトリはコピーするだけ if (directoryName.Contains(ExtensionName.FRAMEWORK) || directoryName.Contains(ExtensionName.BUNDLE) || directoryName == XcodeProjectSetting.IMAGE_XCASSETS_DIRECTORY_NAME) { nextNeedToAddBuild = false; } CopyAndAddBuildToXcode( pbxProject, targetGuid, copyDirectoryPath, buildPath, Path.Combine(currentDirectoryPath, directoryName), nextNeedToAddBuild ); //フレームワークはディレクトリ内を全てコピーしてから、フレームワークごとプロジェクトに追加し、フレームワーク検索パスを通す if (directoryName.Contains(ExtensionName.FRAMEWORK) || directoryName.Contains(ExtensionName.BUNDLE)) { string relativePath = Path.Combine(currentDirectoryPath, directoryName); string fileGuild = pbxProject.AddFile(relativePath, relativePath, PBXSourceTree.Source); if (embedHash.Contains(directoryName)) { pbxProject.AddFileToEmbedFrameworks(targetGuid, fileGuild); pbxProject.AddBuildProperty( targetGuid, XcodeProjectSetting.LD_RUNPATH_SEARCH_PATHS_KEY, "$(inherited) @executable_path/Frameworks" ); } else { pbxProject.AddFileToBuild(targetGuid, fileGuild); pbxProject.AddBuildProperty( targetGuid, XcodeProjectSetting.FRAMEWORK_SEARCH_PATHS_KEY, XcodeProjectSetting.PROJECT_ROOT + currentDirectoryPath ); } } } }
public static void OnPostprocessBuild(BuildTarget buildTarget, string path) { if (buildTarget == BuildTarget.iOS) { string opencvFrameworkPath = Directory.GetDirectories(path, "opencv2.framework", SearchOption.AllDirectories).FirstOrDefault(); if (string.IsNullOrEmpty(opencvFrameworkPath)) { throw new System.Exception("Can't find opencv2.framework"); } string opencvLibraryPath = Directory.GetFiles(path, "libopencvforunity.a", SearchOption.AllDirectories).FirstOrDefault(); if (string.IsNullOrEmpty(opencvLibraryPath)) { throw new System.Exception("Can't find libopencvforunity.a"); } if (PlayerSettings.iOS.sdkVersion == iOSSdkVersion.DeviceSDK) { RemoveSimulatorArchitectures(Path.GetDirectoryName(opencvFrameworkPath), "opencv2.framework/opencv2"); RemoveSimulatorArchitectures(Path.GetDirectoryName(opencvLibraryPath), "libopencvforunity.a"); } #if UNITY_5_0 || UNITY_5_1 || UNITY5_2 string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj"; #else string projPath = PBXProject.GetPBXProjectPath(path); #endif PBXProject proj = new PBXProject(); proj.ReadFromString(System.IO.File.ReadAllText(projPath)); #if UNITY_2019_3_OR_NEWER string target = proj.GetUnityFrameworkTargetGuid(); #elif UNITY_5_0 || UNITY_5_1 || UNITY5_2 string target = proj.TargetGuidByName("Unity-iPhone"); #else string target = proj.TargetGuidByName(PBXProject.GetUnityTargetName()); #endif #if UNITY_2018_1_OR_NEWER #elif UNITY_2017_2_OR_NEWER string fileGuid = proj.FindFileGuidByProjectPath(opencvFrameworkPath.Substring(path.Length + 1)); proj.AddFileToBuild(target, fileGuid); proj.AddFileToEmbedFrameworks(target, fileGuid); foreach (var configName in proj.BuildConfigNames()) { var configGuid = proj.BuildConfigByName(target, configName); proj.SetBuildPropertyForConfig(configGuid, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks"); } #else UnityEngine.Debug.LogError("If the version of Unity is less than 2017.2, you have to set opencv2.framework to Embedded Binaries manually."); #endif #if UNITY_2018_3_0 || UNITY_2018_3_1 || UNITY_2018_3_2 || UNITY_2018_3_3 proj.SetBuildProperty(target, "ENABLE_BITCODE", "NO"); #endif File.WriteAllText(projPath, proj.WriteToString()); #if UNITY_5_5_OR_NEWER if ((int)Convert.ToDecimal(PlayerSettings.iOS.targetOSVersionString) < 8) { #else if ((int)PlayerSettings.iOS.targetOSVersion < (int)iOSTargetOSVersion.iOS_8_0) { #endif UnityEngine.Debug.LogError("Please set Target minimum iOS Version to 8.0 or higher."); } } }
public static void OnPostprocessBuild(BuildTarget buildTarget, string path) { if (buildTarget == BuildTarget.iOS) { string[] guids = UnityEditor.AssetDatabase.FindAssets("OpenCVForUnityIOSBuildPostprocessor"); if (guids.Length == 0) { UnityEngine.Debug.LogWarning("SetPluginImportSettings Faild : OpenCVForUnityIOSBuildPostprocessor.cs is missing."); return; } string opencvForUnityFolderPath = AssetDatabase.GUIDToAssetPath(guids [0]).Substring("Assets/".Length); opencvForUnityFolderPath = opencvForUnityFolderPath.Substring(0, opencvForUnityFolderPath.LastIndexOf("Editor/OpenCVForUnityIOSBuildPostprocessor.cs")); if (PlayerSettings.iOS.sdkVersion == iOSSdkVersion.DeviceSDK) { RemoveSimulatorArchitectures(path + "/Frameworks/" + opencvForUnityFolderPath + "Plugins/iOS/", "opencv2.framework/opencv2"); RemoveSimulatorArchitectures(path + "/Libraries/" + opencvForUnityFolderPath + "Plugins/iOS/", "libopencvforunity.a"); } #if UNITY_5_0 || UNITY_5_1 || UNITY5_2 string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj"; #else string projPath = PBXProject.GetPBXProjectPath(path); #endif PBXProject proj = new PBXProject(); proj.ReadFromString(System.IO.File.ReadAllText(projPath)); #if UNITY_5_0 || UNITY_5_1 || UNITY5_2 string target = proj.TargetGuidByName("Unity-iPhone"); #else string target = proj.TargetGuidByName(PBXProject.GetUnityTargetName()); #endif #if UNITY_2018_1_OR_NEWER #elif UNITY_2017_2_OR_NEWER string frameworkPath = "Frameworks/" + opencvForUnityFolderPath + "Plugins/iOS/opencv2.framework"; string fileGuid = proj.FindFileGuidByProjectPath(frameworkPath); proj.AddFileToBuild(target, fileGuid); proj.AddFileToEmbedFrameworks(target, fileGuid); foreach (var configName in proj.BuildConfigNames()) { var configGuid = proj.BuildConfigByName(target, configName); proj.SetBuildPropertyForConfig(configGuid, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks"); } #else UnityEngine.Debug.LogError("If the version of Unity is less than 2017.2, you have to set opencv2.framework to Embedded Binaries manually."); #endif File.WriteAllText(projPath, proj.WriteToString()); #if UNITY_5_5_OR_NEWER if ((int)Convert.ToDecimal(PlayerSettings.iOS.targetOSVersionString) < 8) { #else if ((int)PlayerSettings.iOS.targetOSVersion < (int)iOSTargetOSVersion.iOS_8_0) { #endif UnityEngine.Debug.LogError("Please set Target minimum iOS Version to 8.0 or higher."); } } }
public static void OnPostprocessBuild(BuildTarget buildTarget, string path) { if (buildTarget == BuildTarget.iOS) { string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj"; PBXProject proj = new PBXProject(); proj.ReadFromFile(projPath); string target = proj.TargetGuidByName(PBXProject.GetUnityTargetName()); string frameworkGUID = proj.FindFileGuidByProjectPath("Frameworks/Plugins/iOS/vlSDK.framework"); proj.AddFileToEmbedFrameworks(target, frameworkGUID); proj.AddBuildProperty(target, "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks"); // Add Frameworks proj.AddFrameworkToProject(target, "Accelerate.framework", false); proj.AddFrameworkToProject(target, "Metal.framework", false); proj.AddFrameworkToProject(target, "GLKit.framework", false); proj.AddFrameworkToProject(target, "ARKit.framework", true); // Disable use of Bitcode proj.SetBuildProperty(target, "ENABLE_BITCODE", "NO"); // Only generate 64bit variants, so set Valid Archs to only "arm64" //proj.SetBuildProperty(target, "ARCHS", "arm64"); //proj.SetBuildProperty(target, "VALID_ARCHS", "arm64"); proj.UpdateBuildProperty(target, "ARCHS", new string[] {}, new string[] { "armv7", "armv7s", "armv7" }); proj.UpdateBuildProperty(target, "VALID_ARCHS", new string[] { "arm64" }, new string[] { "armv7", "armv7s" }); proj.WriteToFile(projPath); // Since iOS 10 it's necessary to add a reason for accessing the // camera to Info.plist. Newer version of Unity allow to set the // usage description inside the editor. For older Versions of // Unity, we add a default value automatically. // Get plist string plistPath = path + "/Info.plist"; PlistDocument plist = new PlistDocument(); plist.ReadFromString(File.ReadAllText(plistPath)); // Get root PlistElementDict rootDict = plist.root; // Set usage description, if not set already string cameraUsageDescriptionKey = "Privacy - Camera Usage Description"; string cameraUsageDescriptionValue = "Augmented Reality"; PlistElementString cameraUsageDescriptionEl = (PlistElementString)rootDict[cameraUsageDescriptionKey]; if (cameraUsageDescriptionEl == null) { rootDict.SetString(cameraUsageDescriptionKey, cameraUsageDescriptionValue); File.WriteAllText(plistPath, plist.WriteToString()); } else if (String.IsNullOrEmpty(cameraUsageDescriptionEl.value)) { cameraUsageDescriptionEl.value = cameraUsageDescriptionValue; File.WriteAllText(plistPath, plist.WriteToString()); } } }