#if UNITY_IOS using System; using System.Collections.Generic; using UnityEditor; using UnityEditor.Callbacks; using System.IO; using Azerion.BlueStack.Editor.iOS.PodDependency; using UnityEditor.iOS.Xcode; namespace Azerion.BlueStack.Editor.iOS { public class BlueStackBuildPostProcess { [PostProcessBuildAttribute(45)] //must be between 40 and 50 to ensure that it's not overriden by Podfile generation (40) and that it's added before "pod install" (50) private static void PostProcessBuild_iOSForPodDependency( BuildTarget target, string pathToBuildProject ) { if (target == BuildTarget.iOS) { CheckInPodFile(pathToBuildProject); } } [PostProcessBuildAttribute(1)] private static void PostProcessBuild_iOS(BuildTarget target, string pathToBuildProject) { DebugHelper.Log("Custom post process build script started executing!"); if (target == BuildTarget.iOS) { string projectPath = PBXProject.GetPBXProjectPath(pathToBuildProject); PBXProject project = new PBXProject(); project.ReadFromFile(projectPath); string unityFrameworkGuid = ""; string mainGameGUID = ""; #if UNITY_2019_3_OR_NEWER mainGameGUID = project.GetUnityMainTargetGuid(); unityFrameworkGuid = project.GetUnityFrameworkTargetGuid(); #else string targetName = PBXProject.GetUnityTargetName(); unityFrameworkGUID = project.TargetGuidByName(targetName); #endif foreach (var dependency in BlueStackSettings.Instance.IOSDependencies) { if (dependency.Alias == "Google Mobile Ads") { AddAdMobApplicationId(pathToBuildProject); break; } } AddSKAdNetworkIdentifier(pathToBuildProject); AddAppTransportSecurity(pathToBuildProject); project.AddBuildProperty(unityFrameworkGuid, "ENABLE_BITCODE", "NO"); // project.AddBuildProperty(unityFrameworkGuid, "OTHER_LDFLAGS", "-ld64"); // Modulemap project.AddBuildProperty(unityFrameworkGuid, "DEFINES_MODULE", "YES"); var moduleFile = pathToBuildProject + "/UnityFramework/UnityFramework.modulemap"; try { if (!File.Exists(moduleFile)) { FileUtil.CopyFileOrDirectory( "Packages/com.azerion.bluestack/Plugins/iOS/UnityFramework.modulemap", moduleFile ); project.AddFile(moduleFile, "UnityFramework/UnityFramework.modulemap"); project.AddBuildProperty( unityFrameworkGuid, "MODULEMAP_FILE", "$(SRCROOT)/UnityFramework/UnityFramework.modulemap" ); DebugHelper.Log("Modulemap copied: " + moduleFile); } else { DebugHelper.Log("Modulemap already exists: " + moduleFile); } } catch (Exception e) { DebugHelper.Log($"Error setting up modulemap: {e.Message}"); } // Headers try { string unityInterfaceGuid = project.FindFileGuidByProjectPath( "Classes/Unity/UnityInterface.h" ); project.AddPublicHeaderToBuild(unityFrameworkGuid, unityInterfaceGuid); string unityForwardDeclsGuid = project.FindFileGuidByProjectPath( "Libraries/com.azerion.bluestack/Plugins/iOS/BSUTypes.h" ); project.AddPublicHeaderToBuild(unityFrameworkGuid, unityForwardDeclsGuid); } catch (Exception e) { DebugHelper.Log($"Error setting up headers: {e.Message}"); } // Save project project.WriteToFile(projectPath); OverWriteMainProject(target, pathToBuildProject); DebugHelper.Log("Custom post process build script finished executing!"); } } private static void AddAdMobApplicationId(string pathToProject) { if (string.IsNullOrEmpty(BlueStackSettings.Instance.AdmobAppIdIOS)) { DebugHelper.StopBuildWithMessage(Constants.APP_IDS_MISSING); } // Open info.plist string plistPath = pathToProject + "/Info.plist"; PlistDocument plist = new PlistDocument(); plist.ReadFromString(File.ReadAllText(plistPath)); PlistElementDict rootDict = plist.root; // Add Admob App ID rootDict.SetString( "GADApplicationIdentifier", BlueStackSettings.Instance.AdmobAppIdIOS ); // Save info.plist File.WriteAllText(plistPath, plist.WriteToString()); } private static void AddAppTransportSecurity(string pathToProject) { // Open info.plist string plistPath = pathToProject + "/Info.plist"; PlistDocument plist = new PlistDocument(); plist.ReadFromString(File.ReadAllText(plistPath)); PlistElementDict rootDict = plist.root; // Add arbitrary loads keys PlistElementDict appTransportDict = rootDict.CreateDict("NSAppTransportSecurity"); appTransportDict.SetBoolean("NSAllowsArbitraryLoads", true); // Save info.plist File.WriteAllText(plistPath, plist.WriteToString()); } private static void AddSKAdNetworkIdentifier(string pathToProject) { // Open info.plist string plistPath = pathToProject + "/Info.plist"; PlistDocument plist = new PlistDocument(); plist.ReadFromString(File.ReadAllText(plistPath)); PlistElementDict rootDict = plist.root; //Add ids for SKAdNetwork PlistElementArray skAdNetworkRoot = rootDict.CreateArray("SKAdNetworkItems"); foreach (string element in Constants.SKAdNetworkIDs) { PlistElementDict value = skAdNetworkRoot.AddDict(); value.SetString(key: "SKAdNetworkIdentifier", val: element); } // Save info.plist File.WriteAllText(plistPath, plist.WriteToString()); } private static void CheckInPodFile(string pathToProject) { var podFilePath = pathToProject + "/Podfile"; if (File.Exists(podFilePath)) { List dependencies = DependencyProvider.GetDependencies( new IOSDependencyParser() ); var result = PodDependencyUtils.CheckPodDependencies( podFilePath: podFilePath, dependencies ); if (result.HasMissingDependency) { DebugHelper.StopBuildWithMessage( result.ErrorMessage + " Please add all the dependencies" ); } } } private static void OverWriteMainProject(BuildTarget target, string path) { if (target == BuildTarget.iOS) { string projPath = PBXProject.GetPBXProjectPath(path); PBXProject proj = new PBXProject(); proj.ReadFromFile(projPath); string targetGuid = proj.GetUnityMainTargetGuid(); foreach (var framework in new[] { targetGuid, proj.GetUnityFrameworkTargetGuid() }) { proj.SetBuildProperty(framework, "ENABLE_BITCODE", "NO"); proj.SetBuildProperty(framework, "EMBEDDED_CONTENT_CONTAINS_SWIFT", "YES"); proj.SetBuildProperty(framework, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "NO"); proj.SetBuildProperty(framework, "SWIFT_VERSION", "5.0"); } proj.WriteToFile(projPath); } } } } #endif