obsidian/笔记文件/2.笔记/xcode依赖处理 打包后处理通过podfile添加第三方库 PostProcessBuildClass.md
2025-04-18 18:26:52 +08:00

11 KiB
Raw Permalink Blame History

#unity/代码缓存 #ios

有一个前提macos已经正确安装了pod相关的工具

PostProcessBuildClass

#if UNITY_IOS
using System.IO;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEngine;
using UnityEditor.iOS.Xcode;

using System.Diagnostics;
using System.Threading;
using Debug = UnityEngine.Debug;
using System;



static class PostProcessBuildClass {
    [PostProcessBuild]
    public static void ChangeXcodePlist(BuildTarget pBuildTarget, string pPath) {
        // Debug.LogError("Post process build ChangeXcodePlist");
        if (pBuildTarget == BuildTarget.iOS) {
            
            
            #region 添加 ATT广告跟踪权限
            AddInfoByTracking(pPath);
            #endregion

            #region 添加Meta 广告变现平台 SKAdNetwork相关
            AddSKAdNetworkItems(pPath);
            #endregion
        }
        
    }
    /// <summary>
    /// 添加广告追踪权限
    /// </summary>
    /// <param name="path"></param>
    private static void AddInfoByTracking(string path)
    {
        string plistPath = Path.Combine(path, "Info.plist");
        PlistDocument plist = new PlistDocument();
        plist.ReadFromFile(plistPath);
        PlistElementDict rootDict = plist.root;

        // 添加广告追踪权限说明
        rootDict.SetString("NSUserTrackingUsageDescription", "We need your consent to track advertisements to provide better services.");

        // 添加定位服务权限说明
        rootDict.SetString("NSLocationWhenInUseUsageDescription", "We need your location to provide personalized services.");

        File.WriteAllText(plistPath, plist.WriteToString());
    }

    /// <summary>
    /// 添加Meta 广告变现平台 SKAdNetwork相关
    /// </summary>
    /// <param name="path"></param>
    private static void AddSKAdNetworkItems(string path)
    {
        string plistPath = Path.Combine(path, "Info.plist");
        PlistDocument plist = new PlistDocument();
        plist.ReadFromFile(plistPath);

        PlistElementDict rootDict = plist.root;

        // 获取或创建SKAdNetworkItems数组
        PlistElementArray skAdNetworkItems;
        if (rootDict.values.ContainsKey("SKAdNetworkItems"))
        {
            skAdNetworkItems = rootDict["SKAdNetworkItems"].AsArray();
        }
        else
        {
            skAdNetworkItems = rootDict.CreateArray("SKAdNetworkItems");
        }

        // 添加SKAdNetworkIdentifier
        AddSkAdNetworkIdentifier(skAdNetworkItems, "v9wttpbfk9.skadnetwork");
        AddSkAdNetworkIdentifier(skAdNetworkItems, "n38lu8286q.skadnetwork");

        // 保存修改
        plist.WriteToFile(plistPath);
    }
    
    private static void AddSkAdNetworkIdentifier(PlistElementArray array, string identifier)
    {
        foreach (var element in array.values)
        {
            if (element.AsDict().values.ContainsKey("SKAdNetworkIdentifier") &&
                element.AsDict()["SKAdNetworkIdentifier"].AsString() == identifier)
            {
                return; // 已存在,不重复添加
            }
        }

        PlistElementDict dict = array.AddDict();
        dict.SetString("SKAdNetworkIdentifier", identifier);
    }
    
    
    private static Thread podFileCheckThread;
    private const int timeOutSeconds = 10;
    
    [PostProcessBuild(1999)]
    public static void OnPostProcessBuild(BuildTarget pBuildTarget, string pPath)
    {
        if (pBuildTarget == BuildTarget.iOS)
        {
            AddSDKFramework(pPath);
            AddSwiftUsed(pPath);
            InitPodFile(pPath);
            AddAudienceNetwork(pPath);
            AddSurveyMonkey(pPath);
            PodInstall(pPath);
        }
    }

    /// <summary>
    /// 如果podfile不存在就自动创建一个新的
    /// </summary>
    private static void InitPodFile(string pPath)
    {
        string podfilePath = Path.Combine(pPath, "Podfile");
        if (!File.Exists(podfilePath))
        {
            string podFileContent = @"
source 'https://cdn.cocoapods.org/'

platform :ios, '12.0'

target 'UnityFramework' do

end
target 'Unity-iPhone' do

end";
            File.WriteAllText(podfilePath, podFileContent);
        }
    }
    
    /// <summary>
    /// 添加调查问卷 相关引用依赖包
    /// </summary>
    /// <param name="pPath"></param>
    private static void AddSurveyMonkey(string pPath)
    {
        string varPodfilePath = Path.Combine(pPath, "Podfile");

        string varPodfileContent = File.ReadAllText(varPodfilePath);
        
        // 检查是否已包含SurveyMonkey
        if (!varPodfileContent.Contains("pod 'surveymonkey-ios-sdk', '~> 2.1.2'"))
        {
            string varInsertionPoint1 = "target 'UnityFramework' do";
            int varIndex1 = varPodfileContent.IndexOf(varInsertionPoint1) + varInsertionPoint1.Length;
            string varToInsert1 = "\n  pod 'surveymonkey-ios-sdk', '~> 2.1.2'";
            varPodfileContent = varPodfileContent.Insert(varIndex1, varToInsert1);
            
            string varInsertionPoint2 = "target 'Unity-iPhone' do";
            int varIndex2 = varPodfileContent.IndexOf(varInsertionPoint2) + varInsertionPoint2.Length;
            string varToInsert2 = "\n  pod 'surveymonkey-ios-sdk', '~> 2.1.2'";
            varPodfileContent = varPodfileContent.Insert(varIndex2, varToInsert2);
            File.WriteAllText(varPodfilePath, varPodfileContent);
        }
    }
    
    /// <summary>
    /// 添加meta广告变现
    /// </summary>
    /// <param name="pPath"></param>
    private static void AddAudienceNetwork(string pPath)
    {
        string varPodfilePath = Path.Combine(pPath, "Podfile");

        string varPodfileContent = File.ReadAllText(varPodfilePath);
        
        // 检查是否已包含SurveyMonkey
        if (!varPodfileContent.Contains("pod 'FBAudienceNetwork'"))
        {
            string varInsertionPoint1 = "target 'UnityFramework' do";
            int varIndex1 = varPodfileContent.IndexOf(varInsertionPoint1) + varInsertionPoint1.Length;
            string varToInsert1 = "\n  pod 'FBAudienceNetwork'";
            varPodfileContent = varPodfileContent.Insert(varIndex1, varToInsert1);
            
            File.WriteAllText(varPodfilePath, varPodfileContent);
        }
    }

    /// <summary>
    /// 添加广告SDK 相关引用依赖包
    /// </summary>
    /// <param name="pPath"></param>
    private static void AddAdvertisement(string pPath)
    {
        string varPodfilePath = Path.Combine(pPath, "Podfile");

        string varPodfileContent = File.ReadAllText(varPodfilePath);

        bool needWrite = false;

        // 检查是否已包含广告引用
        if (!varPodfileContent.Contains("pod 'TPNiOS'"))
        {
            string varInsertionPoint1 = "target 'UnityFramework' do";
            int varIndex1 = varPodfileContent.IndexOf(varInsertionPoint1) + varInsertionPoint1.Length;
            string varToInsert1 = "\n   pod 'TPNiOS'";
            varPodfileContent = varPodfileContent.Insert(varIndex1, varToInsert1);
            needWrite = true;
        }
        
        if (!varPodfileContent.Contains("pod 'TPNUnityAdsSDKAdapter'"))
        {
            string varInsertionPoint1 = "target 'UnityFramework' do";
            int varIndex1 = varPodfileContent.IndexOf(varInsertionPoint1) + varInsertionPoint1.Length;
            string varToInsert1 = "\n   pod 'TPNUnityAdsSDKAdapter'";
            varPodfileContent = varPodfileContent.Insert(varIndex1, varToInsert1);
            needWrite = true;
        }
        
        if (!varPodfileContent.Contains("pod 'TPNAdmobSDKAdapter'"))
        {
            string varInsertionPoint1 = "target 'UnityFramework' do";
            int varIndex1 = varPodfileContent.IndexOf(varInsertionPoint1) + varInsertionPoint1.Length;
            string varToInsert1 = "\n   pod 'TPNAdmobSDKAdapter'";
            varPodfileContent = varPodfileContent.Insert(varIndex1, varToInsert1);
            needWrite = true;
        }
        

        if (needWrite)
        {
            File.WriteAllText(varPodfilePath, varPodfileContent);
        }
    }
    
    private static void AddSDKFramework(string pPath)
    {
        string projPath = PBXProject.GetPBXProjectPath(pPath);
        PBXProject proj = new PBXProject();
        proj.ReadFromFile(projPath);
        string target = proj.GetUnityMainTargetGuid();
        
        proj.AddFrameworkToProject(target, "StoreKit.framework", false); //添加商店评价相关
        
        proj.WriteToFile(projPath);
    }
    
    /// <summary>
    /// 添加 总是允许使用Swift编译
    /// </summary>
    /// <param name="pPath"></param>
    private static void AddSwiftUsed(string pPath)
    {
        // 获取Xcode项目路径
        string projPath = PBXProject.GetPBXProjectPath(pPath);
        PBXProject proj = new PBXProject();
        proj.ReadFromFile(projPath);

        // 获取主目标
        string targetGuid = proj.GetUnityMainTargetGuid();

        // 设置"Always Embed Swift Standard Libraries"为YES
        proj.SetBuildProperty(targetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES");

        // 保存修改
        proj.WriteToFile(projPath);
    }
    
    /// <summary>
    /// 执行pod install同步方式
    /// </summary>
    private static void PodInstall(string pPath)
    {
        Debug.Log("=== 开始执行Pod安装流程 ===");
        
        if (!Directory.Exists(pPath))
        {
            Debug.LogError($"Xcode工程路径不存在: {pPath}");
            return;
        }

        string podfilePath = Path.Combine(pPath, "Podfile");
        if (!File.Exists(podfilePath))
        {
            Debug.LogError($"Podfile文件不存在: {podfilePath}");
            return;
        }

        try
        {
            // 转义路径中的单引号
            string escapedPath = pPath.Replace("'", "'\\''");
            
            string appleScript = $@"
            tell application ""Terminal""
                activate
                do script ""cd '{escapedPath}' && pod install && exit""
            end tell";

            Debug.Log($"正在启动终端执行pod install...");
            
            using (Process process = new Process())
            {
                process.StartInfo = new ProcessStartInfo
                {
                    FileName = "/usr/bin/osascript",
                    Arguments = $"-e '{appleScript}'",
                    UseShellExecute = false,
                    RedirectStandardError = true,
                    CreateNoWindow = true
                };

                process.Start();
                process.WaitForExit();

                if (process.ExitCode != 0)
            {
                    string error = process.StandardError.ReadToEnd();
                    Debug.LogError($"启动终端失败: {error}");
                }
                else
                {
                    Debug.Log("已启动终端执行pod install请稍后在终端中查看结果");
                }
            }
        }
        catch (Exception ex)
        {
            Debug.LogError($"执行命令时发生异常: {ex}");
        }
        
        Debug.Log("=== Pod安装流程结束 ===");
    }

}
#endif