ios打包是比较麻烦的,配通一次流程后需要做个笔记把各种插件各种配置在每次打包的时候重新配置,作为一个程序员当然不能接受这么笨的事情,写个脚本让代码去实现这些。

首先,介绍一个标记

[PostProcessBuild]

在函数前写上这个标记,unity在打完包后便会调用这个函数。

所以我们也将用这个标记让unity在包打成xcode项目以后,去改动xcode里面的配置。

而unity也有一个默认的函数给我们使用

static void OnPostprocessBuild(BuildTarget target,string pathToBuildProject)  

target就是打包的目标,是android还是ios还是其他,pathToBuildProject是打完包后的路径。
所以,主函数就是这样

[PostProcessBuild]  
static void OnPostprocessBuild(BuildTarget target,string pathToBuildProject)  
{  
}  

接下来是添加framework和一些系统插件和设置buildSetting


    public static void ModifyProj(string pathToBuildProject){
        string _projPath = PBXProject.GetPBXProjectPath (pathToBuildProject);
        PBXProject _pbxProj = new PBXProject ();

        _pbxProj.ReadFromString (File.ReadAllText (_projPath));
        string _targetGuid = _pbxProj.TargetGuidByName ("Unity-iPhone");

        //*******************************添加framework*******************************//
        _pbxProj.AddFrameworkToProject (_targetGuid, "Security.framework", true);
        _pbxProj.AddFrameworkToProject (_targetGuid, "JavaScriptCore.framework", true);

        //*******************************添加tbd*******************************//
        _pbxProj.AddFileToBuild(_targetGuid, _pbxProj.AddFile("usr/lib/libz.1.dylib", "Frameworks/libz.1.dylib", PBXSourceTree.Sdk));

        //*******************************设置buildsetting*******************************//
        //_pbxProj.SetBuildProperty (_targetGuid, "CODE_SIGN_IDENTITY", code_sign_identity);  

        File.WriteAllText(_projPath, _pbxProj.WriteToString());
    }

把主函数的路径传进去就可以了。
中间注释的那行就是设置buildSetting,项目暂时还没用就屏蔽了,具体要怎么传参数可能还需要百度一下

之后就是修改plist

    static void SetPlist(string pathToBuildProject)
    {
        string _plistPath = pathToBuildProject + "/Info.plist";
        PlistDocument _plist = new PlistDocument ();

        _plist.ReadFromString (File.ReadAllText (_plistPath));
        PlistElementDict _rootDic = _plist.root;

        //*******************************设置plist属性*******************************//
        _rootDic.SetString ("Privacy - Microphone Usage Description", "microphoneDesciption");
        _rootDic.SetString ("Bundle version", "6");
        _rootDic.SetString ("Bundle versions string, short", "0.0.2");
        _rootDic.SetString ("Privacy - Media Library Usage Description", "App需要您的同意,才能访问媒体资料库");
        _rootDic.SetString ("Privacy - Bluetooth Peripheral Usage Description", "App需要您的同意,才能访问蓝牙");
        _rootDic.SetString ("Privacy - Calendars Usage Description", "App需要您的同意,才能访问日历");
        _rootDic.SetString ("Privacy - Camera Usage Description", "App需要您的同意,才能访问相机");
        _rootDic.SetString ("Privacy - Contacts Usage Description", "是否允许此App访问您的通讯录?");
        _rootDic.SetString ("Privacy - Health Share Usage Description", "App需要您的同意,才能访问健康分享");
        _rootDic.SetString ("Privacy - Health Update Usage Description", "App需要您的同意,才能访问健康更新 ");
        _rootDic.SetString ("Privacy - Location Always Usage Description", "App需要您的同意,才能始终访问位置");
        _rootDic.SetString ("Privacy - Location Usage Description", "App需要您的同意,才能访问位置");
        _rootDic.SetString ("Privacy - Location When In Use Usage Description", "是否允许此App访问您的地理位置?");
        _rootDic.SetString ("Privacy - Motion Usage Description", "App需要您的同意,才能访问运动与健身");
        _rootDic.SetString ("Privacy - Photo Library Usage Description", "App需要您的同意,才能访问相册");
        _rootDic.SetString ("Privacy - Reminders Usage Description", "App需要您的同意,才能访问提醒事项");

        File.WriteAllText(_plistPath, _plist.WriteToString());
    }

基本上这样就算搞定了。

不过ios打包一般为了快一点的话,一般会把asset文件夹拿出来再打完包后放回去(或者像我们项目,资源是策划准备好上传到svn,所以资源文件夹不在项目里面的,这种情况下就代码复制过去)

[MenuItem("测试/测试")]
    static void CopyAssetToXCode(string pathToBuildProject)
    {
        string assetFolderName = pathToBuildProject + "/Data/Raw/";

        DirectoryInfo dir = new DirectoryInfo (IOS_RESOURCE_FOLDER_PATH);
        DirectoryInfo[] allDirs = dir.GetDirectories ();
        DirectoryInfo latestDir = null;
        foreach (DirectoryInfo d in allDirs) 
        {
            if (latestDir == null)
                latestDir = d;
            else
            {
                if (latestDir.LastWriteTime.Ticks < d.LastWriteTime.Ticks)
                    latestDir = d;
            }
        }

        if (latestDir == null) 
        {
            Debug.LogError ("错误!!无法复制Asset资源!!!!!");
            return;
        }

        Directory.CreateDirectory (assetFolderName + "assets");
        CopyDirectory (latestDir + "/resources_1first/assets", assetFolderName + "assets");

        File.Copy(latestDir + "/版本导出后文件存放/version.ini",assetFolderName + "version.ini");

        Debug.LogError ("复制Asset到xcode...完成!");
        Debug.LogError ("Asset原资源路径:" + latestDir);

    }

    static void CopyDirectory(string sourceDirectory, string targetDirectory) 
    {
        if (!Directory.Exists(sourceDirectory) || !Directory.Exists(targetDirectory)) 
        {
            return;
        }
        DirectoryInfo sourceInfo = new DirectoryInfo(sourceDirectory);
        FileInfo[] fileInfo = sourceInfo.GetFiles();
        foreach (FileInfo fiTemp in fileInfo) 
        {
            //if(!fiTemp.Name.StartsWith("."))
                File.Copy(sourceDirectory + "/" + fiTemp.Name, targetDirectory + "/" + fiTemp.Name, true);
        }
        DirectoryInfo[] diInfo = sourceInfo.GetDirectories();
        foreach (DirectoryInfo diTemp in diInfo) 
        {
            string sourcePath = diTemp.FullName;
            string targetPath = diTemp.FullName.Replace(sourceDirectory,targetDirectory);
            Directory.CreateDirectory(targetPath);
            CopyDirectory(sourcePath,targetPath);
        }
    }

所以最后主函数就是这样

    [PostProcessBuild]
    static void OnPostprocessBuild(BuildTarget target, string pathToBuildProject)
    {
        Debug.LogError ("修改xcode插件及其他配置...开始!");
        ModifyProj (pathToBuildProject);
        Debug.LogError ("修改xcode插件及其他配置...完成!");

        Debug.LogError ("修改xcode,plist...开始!");
        SetPlist (pathToBuildProject);
        Debug.LogError ("修改xcode,plist...完成!");

        Debug.LogError ("复制Asset到xcode...开始!");
        CopyAssetToXCode (pathToBuildProject);
    }