使用 Jenkins 从 Unity 工程自动化导出 iOS 包

 

//Unity导出XCode替换资源流程/

Untiy 工程导出 Xcode 后通常需要修改一些 iOS 相关的配置,如果每次导出 Xcode 都去修改会比较浪费时间,这里介绍一种简单快捷的做法。

Untiy 导出的 Xcode 工程的目录结构

使用 Jenkins 从 Unity 工程自动化导出 iOS 包_第1张图片

通过 git 比较发现,Untiy 工程内容通常会影响到 Xcode DataClassesLibraries 下的内容,所以我们可以先配置好一个 Xcode 工程,需要重新打包时就重新导出一个 Xcode,然后把新 Xcode 下的 DataClassesLibraries 替换到旧的工程里。

配置流程

  1. 打开配置好的 Xcode 工程,选中 Data Classes Libraries,以 Move to Trash 方式删除
  2. 使用 Untiy 导出新的 Xcode,将新工程的 Data Classes Libraries 复制到旧工程中相同的位置。
  3. 在旧工程中添加 Classes Libraries 文件,以 create groups 方式添加
  4. 在旧工程中添加 Data 文件,以 create folder references 方式添加

注意事项

2 步可不是多余的哦 ,如果不执行第二步,直接去新 Xcode 目录下添加 DataClassesLibraries,这样编译工程时有可能报错。

这种报错应该是 Xcode 的一个 BugXcode 添加文件是需要对每个文件生成索引并写入 pbxproj 文件中,我们公司的 Classes 文件下有 2w 多个 c++ 文件,整个过程就要 10 分钟左右,可能因为文件数量太多导致有时侯引用添加上了,但文件没有复制进工程。经过多次实验,只有按以上流程走才能保证正常编译。

高效做法

这种方式需要耗费时间较久,采用 Jenkins 自动化构建 可以节省不少时间。

 

/// Jenkins自动打包UnityIOS//

Unity iOS 平台的包过程比较繁琐,手动操作会比较浪费时间还容易出错。这里把一些出包参数放在了 Jenkins 上配置,再结合 ShellPython 脚本执行参数化构建,实现整个流程的自动化。

Unity iOS 包的流程,可以看做下面三步,下面讲解每一步如何用脚本来执行,最后用 Jenkins 将整个流程串起来,实现在 Jenkins 上选择参数后一键打包。

  1. Unity 工程导出 Xcode 工程
  2. 配置 Xcode 工程,往 Xcode 里添加 iOS SDK 文件并修改 Xcode 编译配置
  3. Xcode 工程导出 ipa 包

Unity 工程导出 Xcode 工程

使用 UnityEditor

UnityEditor 提供了生成 Xcode 和修改 Xcode 工程配置的 Api

Unity 工程 Editor 目录下新建一个 iOSBuilder.cs,内容如下:

using UnityEngine;

using System.Collections;

using System.Collections.Generic;

using UnityEditor;

 

public class iOSBuilder:Editor

{

         public static void Build()

         {

                 SetUnityParams ();

                 // UnityEditor.BuildPipeline 提供了一个函数`BuildPlayer`用来从 Untiy 工程导出成 Xcode 工程。

                 BuildPipeline.BuildPlayer(ProjectBuilder.GetBuildScenes(), "/Users/zhangning/Desktop/test", BuildTarget.iOS, BuildOptions.None);

         }

 

         void SetUnityParams()

         {

                 foreach(string arg in System.Environment.GetCommandLineArgs())

                 {

                          if(arg.StartsWith("project-", System.StringComparison.Ordinal))

                          {

                                   ModifyPlayerSetting(arg.Replace("project-", ""), BuildTargetGroup.iOS);

                          }

                 }

         }

 

         //修改 Xcode 参数,

         void ModifyPlayerSetting(string arg, BuildTargetGroup targetGroup)

         {

                 string[] argsArray = arg.Split(';');

                 for (int i = 0; i < argsArray.Length; i++)

                 {

                          string[] argSprite = argsArray[i].Split('=');

                          if (argSprite.Length != 2)

                                   continue;

                          switch (argSprite[0].Trim())

                          {

                                   // UnityEditor.PlayerSettings 提供了各种修改 Xcode 工程基础配置的 Api,比如包名、版本号等

                                   case "bundleIdentifier":

                                            PlayerSettings.applicationIdentifier = argSprite[1];

                                            break;

                                   case "bundleVersion":

                                            PlayerSettings.bundleVersion = argSprite[1];

                                            break;

                                   case "productName":

                                            PlayerSettings.productName = argSprite[1];

                                            break;

                          }

                 }

         }

}

当执行iOSBuilder.Build时,就会导出一个 Xcode 工程。

Shell 中调用 C# 的方法

我们最终的目的是使用命令执行所有的操作,所以需要使用脚本调用iOSBuilder.Build

新建一个 build.sh,内容如下:

# Unity 程序路径

UNITY_PATH=/Applications/Unity/Unity.app/Contents/MacOS/Unity

 

# Unity 工程路径

PROJECT_PATH=/Users/zhangning/demo

 

# iOSBuilder SetUnityParams 会读取这些参数,并作用于 PlaySetting

buildArgs="bundleIdentifier=test.com;bundleVersion=1.0"

 

# 执行 iOSBuilder 方法

$UNITY_PATH -projectPath ${ PROJECT_PATH} -executeMethod iOSBuilder.Build project-$buildArgs -quit

这里的参数都是可灵活配置的,为后面 Jenkins 一键打包做准备。

配置 Xcode 工程

Unity 应用有时候会需要调用一些 iOS 原生的 Api,这个交互流程这里不做详述,通常是在 C# 层定义好接口然后直接调用,然后在 OC 层去实现对应的接口。这时候就需要在导出 Xcode 后添加一些 OC 文件和依赖库,以及修改一些编译配置。

操作 Xcode 配置的几种方法

Xcode 是通过 pbxproj 文件来查找项目中的文件和工程的编译配置,pbxproj 通过 交叉 UUID 来索引,不方便直接读取和修改,下面这些库都是用来操作 pbxproj 文件的。

插件

问题

mod-pbxproj

无法修改 Xcode Capabilities

XUPorter

作者不维护了,有一些 Bug 和功能缺陷

UnityEditor.iOS.Xcode

需要较高版本的 Unity

XUPorter UnityEditor.iOS.Xcode 都是使用 C# 开发。Untiy [PostProcessBuild] 标签标注的函数会在导出 Xcode 后自动调用,我们可以在此函数中调用这两个插件来配置 Xcode,这样即使手动导出的 Xcode 也无需重复配置,是种不错的做法。

个人对 python 更熟悉一些,也基本没有手动出包的需求,就在 mod-pbxproj 的基础上开了一套 Xcode 相关工具 XcodeEditor,添加了对 Xcode Capability 的修改,并提供了 ini 配置文件来表示 Xcode 中的各个选项,方便 Untiy 开发人员使用。

使用 XcodeEditor

新建 start.py,添加以下内容:

from xcodetools import *

 

config_path ='/Users/zhangning/Desktop/config.ini'

 

project_path = '/Users/zhangning/Desktop/test'

 

Xcode.modify(project_path, config_path)

参考 配置规则,将 Xcode 配置写在一个 .ini 文件中,然后在 build.sh 中追加以下内容:

python3 /Users/zhangning/Desktop/XcodeEditor/start.py

执行 build.sh,就会得到一个配置完善的 Xcode,剩下来就是打包的事了。

Xcode 工程导出 ipa

Xcode 自动化打包网上教程已经太多了,我在 XcodeEditor 中封装了 Package 模块,传入所需参数即可导出一个 ipa 包。

使用方法如下:

from xcodetools import Package

 

project_path = '/Users/zhangning/Desktop/test'

 

ipa_path = '/Users/zhangning/Desktop/IPA/test.ipa'

 

plist = '/Users/zhangning/Desktop/ExportOptions.plist'

 

# 开始自动打包

Package.build (project_path, ipa_path, plist)

为了将所有操作放在一个脚本里,我们再修改一下上一步中的 start.py build.sh,并将每次打包时会变的参数改为从环境变量中获取。

start.py

from xcodetools import *

 

config_path ='/Users/zhangning/Desktop/config.ini'

 

project_path = '/Users/zhangning/Desktop/test'

 

ipa_path = '/Users/zhangning/Desktop/IPA/test.ipa'

 

plist = '/Users/zhangning/Desktop/ExportOptions.plist'

 

Xcode.modify(project_path, config_path)

 

Package.build(project_path, ipa_path, plist)

 

build.sh

bundleIdentifier=$1

bundleVersion=$2

commitId=$3

 

# Unity 程序路径

UNITY_PATH=/Applications/Unity/Unity.app/Contents/MacOS/Unity

 

# Unity 工程路径

PROJECT_PATH=/Users/zhangning/demo

 

# 更新工程

cd ${ PROJECT_PATH}

git clean -f

git reset --hard ${ commitId}

 

# iOSBuilder SetUnityParams 会读取这些参数,并作用于 PlaySetting

buildArgs="bundleIdentifier=${ bundleIdentifier};bundleVersion=${ bundleVersion}"

 

# 执行 iOSBuilder 方法

$UNITY_PATH -projectPath ${ PROJECT_PATH} -executeMethod iOSBuilder.Build project-$buildArgs -quit

 

# 配置 Xcode 并打包

python3 /Users/zhangning/Desktop/XcodeEditor/start.py

Jenkins 一键打包

现在只要这样执行 build.sh 就可以得到一个需要的 ipa 包了

./build.sh bundleIdentifier bundleVersion commitId

使用 Jenkins 参数化构建功能

Jenkins 配置中勾选参数化构建,并添加以下参数:

使用 Jenkins 从 Unity 工程自动化导出 iOS 包_第2张图片

添加执行 shell 指令:

使用 Jenkins 从 Unity 工程自动化导出 iOS 包_第3张图片

启动该配置,设置相关参数后点击开始构建。

使用 Jenkins 从 Unity 工程自动化导出 iOS 包_第4张图片

总结

本文介绍了如何使用脚本来执行 Untiy 导出 iOS 包的每一步操作,并在最后将一些参数配置在 Jenkins 上,借助于 Jenkins 的参数化构建功能,让非开发人员也可以自由打包。

在例子中只要在 Jenkins 上选择一个包名,填一下版本号和 git commitId 即可打出一个包,这里的参数仅为示例,主要是提供了一种自动化构建的思路,使用时需要结合业务需求,在各个环节间新增脚本任务或参数。

/

你可能感兴趣的:(Unity3d优化相关)