Unity 自动化打包XCode工程

Unity 自动化打包XCode工程

每次打包都要手动修改Xcode的各种配置,于是研究了一下通过Unity提供的API设置XCode的各种配置


XCode签名

  • 在我使用的Unity版本中(Unity2018.2)可以通过代码为XCode签名,PlayerSetting还可以设置权限等各种设置,具体请自行查看API:
//xxxx为你的证书的ID
PlayerSettings.iOS.appleDeveloperTeamID = xxxx;
PlayerSettings.iOS.appleEnableAutomaticSigning = true;
  • unity提供一套api去修改xcode项目工程配置以及修改plist文件内容(当unity build结束后, 会自动回调OnPostProcessBuild) 新建一个脚本实现OnPostProcessBuild
[PostProcessBuild]
  public static void OnPostprocessBuild(BuildTarget bulidTarget, string path)
   {
       //Debug.Log("iOS 打包回调配置");
        if (bulidTarget != BuildTarget.iOS) return;
   	//基础配置,得到工程的targetGuid 
       string projectPath = PBXProject.GetPBXProjectPath(path);
       PBXProject project = new PBXProject();
       string fileText = File.ReadAllText(projectPath);
       project.ReadFromString((fileText));
       string targetGuid = project.TargetGuidByName(PBXProject.GetUnityTargetName());
       //"z.entitlemests"名字自取
       var capManager = new ProjectCapabilityManager(projectPath, "z.entitlements", PBXProject.GetUnityTargetName());

       //capability设置
       SetCapabilities(capManager);

       //BuildSetting
       SetBuidSetting(project, targetGuid, projectPath);

       //framework
       AddFramework(project, targetGuid, projectPath);

       //plist文件
       AddPlist(path);

       //代码
       AddiosCode(path);
}
  • 开启XCode Capabilities面板下的各种开关(列举两个,其它自查文档)
 private static void SetCapabilities(ProjectCapabilityManager manager)
 {
      //推送
       manager.AddPushNotifications(true);
       //内购
       manager.AddInAppPurchase();
       manager.WriteToFile();
  }
  • 设置XCode自带的Framework,至于第三方库,放到Unity工程的Plungins/iOS目录下会自动引用

     string[] umengFrameworkArr = { "libz.dylib", "CoreTelephony.framework", "libz.tbd", "libsqlite3.tbd", "CoreGraphics.framework" };
      foreach (string str in umengFrameworkArr)
      {
       project.AddFrameworkToProject(targetGuid,str,false);
      }	
    
  • 设置XCode BuildSetting

   string linkerFlag = "OTHER_LDFLAGS";
   project.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO");
   project.AddBuildProperty(targetGuid, linkerFlag, "-ObjC"); 
   project.AddBuildProperty(targetGuid, linkerFlag, "-all_load");
   project.AddBuildProperty(targetGuid, linkerFlag, "-licucore");

效果如图:每个属性的名字在右边的Quick Help中可以看到
Unity 自动化打包XCode工程_第1张图片

  • 修改Plist文件(以Umeng为例)
    static void AddPlist(string projPath)
   {
       string plistPath = projPath + "/Info.plist";
       PlistDocument plist = new PlistDocument();
       plist.ReadFromString(File.ReadAllText(plistPath));

       PlistElementDict rootDic = plist.root;

       //不设置这项,提交时会显示缺少合规证明
       rootDic.SetBoolean("ITSAppUsesNonExemptEncryption", false);
       rootDic.SetString("NSCameraUsageDescription", "$(PRODUCT_NAME)想用下你的相机啦"); //相机
       rootDic.SetString("NSMicrophoneUsageDescription", "$(PRODUCT_NAME)想要使用麦克风");//mic
       rootDic.SetString("NSPhotoLibraryUsageDescription", "$(PRODUCT_NAME)想要访问相册");
       rootDic.SetString("NSLocationWhenInUseUsageDescription", "$(PRODUCT_NAME)需要获取您的当前位置");

       PlistElementArray urlTypes = rootDic.CreateArray("CFBundleURLTypes");
       string[] urlSchemes = { "微信key","腾讯qqKey","QQ16进制"};
       foreach(string str in urlSchemes)
       {
           PlistElementDict typeRole = urlTypes.AddDict();
           typeRole.SetString("CFBundleTypeRole", "Editor");
           PlistElementArray urlScheme = typeRole.CreateArray("CFBundleURLSchemes");
           urlScheme.AddString(str);   
       }
       PlistElementArray queriesSchemes = rootDic.CreateArray("LSApplicationQueriesSchemes");
       string[] queriesArr = { "mqqapi",
           "mqq",
           "mqqOpensdkSSoLogin",
           "mqqconnect",
           "mqqopensdkdataline",
           "mqqopensdkgrouptribeshare",
           "mqqopensdkfriend",
           "mqqopensdkapi",
           "mqqopensdkapiV2",
           "mqqopensdkapiV3",
           "mqqopensdkapiV4",
           "mqzoneopensdk",
           "wtloginmqq",
           "wtloginmqq2",
           "mqqwpa",
           "mqzone",
           "mqzonev2",
           "mqzoneshare",
           "wtloginqzone",
           "mqzonewx",
           "mqzoneopensdkapiV2",
           "mqzoneopensdkapi19",
           "mqzoneopensdkapi",
           "mqqbrowser",
           "mttbrowser",
           "wechat",
           "weixin"};
       foreach(string str in queriesArr)
       {
           queriesSchemes.AddString(str);  
       }

       PlistElementDict arbitraryLoad = rootDic.CreateDict("NSAppTransportSecurity");
       arbitraryLoad.SetBoolean("NSAllowsArbitraryLoads", true);
       File.WriteAllText(plistPath, plist.WriteToString());
  • 在Unity写iOS代码U3D似乎还没支持(反正我是没找到- -),所以我把XUPorter插件中的XClass脚本拿过来直接用了,具体使用方法以及相应脚本请自行百度
//根据路径获取OC文件
XClass UnityAppController = new XClass(projectPath+"/Classes/UnityAppController.mm");
//查找是否有#include "AppDelegateListener.h"这行代码,有的话则在这行代码下面添加#import	
UnityAppController.WriteBelow("#include \"PluginBase/AppDelegateListener.h\"",
                                      "#import  ");
UnityAppController.WriteBelow("#include \"PluginBase/AppDelegateListener.h\"",
                                      "#import \"UNUMConfigure.h\" ");
  • 最后附上XClass源码:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;

public partial class XClass : System.IDisposable
{

    private string filePath;

    public XClass(string fPath)
    {
        filePath = fPath;
        if (!System.IO.File.Exists(filePath))
        {
            Debug.LogError(filePath + "路径下文件不存在");
            return;
        }
    }


    public void WriteBelow(string below, string text)
    {
        StreamReader streamReader = new StreamReader(filePath);
        string text_all = streamReader.ReadToEnd();
        streamReader.Close();

        if (text_all.Contains(text)) text_all.Replace(text, string.Empty);

        int beginIndex = text_all.IndexOf(below);
        if (beginIndex == -1)
        {
            Debug.LogError(filePath + "中没有找到标致" + below);
            return;
        }

        int endIndex = text_all.LastIndexOf("\n", beginIndex + below.Length);

        text_all = text_all.Substring(0, endIndex) + "\n" + text + "\n" + text_all.Substring(endIndex);

        StreamWriter streamWriter = new StreamWriter(filePath);
        streamWriter.Write(text_all);
        streamWriter.Close();
    }

    public void Replace(string below, string newText)
    {
        StreamReader streamReader = new StreamReader(filePath);
        string text_all = streamReader.ReadToEnd();
        streamReader.Close();

        int beginIndex = text_all.IndexOf(below);
        if (beginIndex == -1)
        {
            Debug.LogError(filePath + "中没有找到标致" + below);
            return;
        }

        text_all = text_all.Replace(below, newText);
        StreamWriter streamWriter = new StreamWriter(filePath);
        streamWriter.Write(text_all);
        streamWriter.Close();

    }

    public void Dispose()
    {

    }
}

你可能感兴趣的:(Unity)