Unity自动化&IOS自动化签包
Unity自动化打包
本章节主要是为了学习Unity自动化打包相关知识以及运用。
本文大部分属于本人学习理解的东西,如有不对欢迎指出,学习交流,共同进步。
本章节的流程如下:
- 了解什么是打包以及打包过程中的一些相关概念
- 了解什么是自动化以及帮助我们快速完成一键打包的工具
- 自动化打包工具或编程语言的选取
- Unity自动化打包过程中的相关工具
- 实战集成运用到Unity构建一键打包
- 更多学习程序发布以及相关概念
在了解相关自动化工具之前,我们需要先简单了解下什么是版本控制。在我们的日常开发工作中必不可少。
版本控制
打包
平时做游戏开发,在完成整个游戏功能开发后,需要通过打包上真机测试。
把所有游戏资源代码打包成安装包的过程称为打包。
多平台
在多平台的处理上,Unity已经帮我们做了很大一部分工作了。让我们大部分时间只需关心游戏核心开发(Unity部分API在不同平台有差异),在打包这一块只需打选择对应平台即可。
但Unity自带的打包,终究只包含最基本的打包流程,当我们有特殊需求时,我们需要通过Unity以及相关工具完成支持我们自定义的打包流程。
自动化
在了解什么是自动化之前,让我们看看打包的基本流程。
在打包过程中,打包往往包含4个步骤。
- Preprocess(打包准备步骤)
这一步主要是为正式打包编译做准备,比如做一些平台相关设置,资源打包处理,文件复制等 - Build(打包编译步骤)
这一步是程序代码和资源正式打包成安装包的步骤,主要是通过指定打包参数执行打包。
Unity在打包到Android和IOS平台时有差异。Android是直接就打包出APK,而IOS要先打包成XCode工程,然后在通过编译XCode工程打包出Ipa安装包。 - Postprocess(打包结束后期处理步骤)
这一步是打包完成后负责后续的自动化操作以及善后工作,比如在打包IOS时打包出XCode工程后,可以在这一步进行XCode工程的自动化处理部分(比如动态添加info.plist文件信息,动态插入代码等) - Deploy(安装步骤)
这一步主要是打包好的安装包安装到真机的步骤
如果没有自动化,我们需要一步一步人工手动去完成上面的步骤。
而自动化就是只需人工设置打包最基本的参数信息,然后通过一步就自动化完成上述步骤的过程。
Jenkins
本人使用目的:
做Unity游戏打包机,持续集成自动化打包流程,做到一键打包。
- Download Jeakins
- Open up a terminal in the download directory and run java -jar jenkins.war
- Browse to http://localhost:8080 and follow the instructions to complete the installation.(安装插件)
Jenkins实战
自由风格构建系统
主要是采用特定的构建系统去构建自动化。(比如java通过ant||Maven,windows通过bat||python等)
如果不想采用Pipeline编写自动化流程,也可以通过直接编写调用Windows Bat或者Python等命令触发自动化流程。
Unity3d Plugin不支持Pipeline,所以为了使用Unity3d Plugins,这里采用自由风格构建系统来搭建Unity3D的自动化打包。
- Create Free Style(创建自由风格项目)
新建 -> 构建一个自由风格的软件项目 - 设置参数构造(用于自定义参数添加)
- 设置代码来源
- 设置构建命令(bat || python || unity3d……)
- 设置构建完毕后的一些行为(比如邮件通知)
Note:
想要改变默认的workspace路径的话。
设置->使用自定义的工作空间(只针对当前设置的自由风格项目有效)
Pipeline
What
Jenkins Pipeline is a suite of plugins which supports implementing and integrating continuous delivery pipelines into Jenkins. Pipeline provides an extensible set of tools for modeling simple-to-complex delivery pipelines “as code”.(这里的Pipeline是一套插件,用于支持持续自动化集成编写。好比脚本文件定义一系列的自动化流程,但并不等价于脚本。)
那么Pipeline是用什么语言编写了?
Jenkins是基于Java的,Pipeline的编写是基于Groovy。
Groovy是Java平台上设计的面向对象编程语言。这门动态语言拥有类似Python、Ruby和Smalltalk中的一些特性,可以作为Java平台的脚本语言使用。
Why
为什么需要Pipeline?
- Code — 可管理可编辑可视化的自动化流程脚本
- Durable — 可持续化开发
- Pausable — 可以自动也可以停止等待输入
- Versatile — 支持复杂的持续交付需求
- Extensible — “The Pipeline plugin supports custom extensions to its DSL [5: Domain-Specific
Language] and multiple options for integration with other plugins.”
How
接下来让我们看看如何创建一个Pipeline。
- 下载Pipeline插件
- New Item — 新建Pipeline(选择Pipeline类型)
- Configure Pipeline
- 配置Pipeline的名字
- 设置Jenkins Pipeline Code的来源
- 网页版编写
- SVN下含Jenksfile文件
这里不深入讨论Jenkins的各种设置,详情查看官方文档Jenkins User Handbook
- 网页版编写
- 配置Pipeline的名字
Note:
Pipeline supports two syntaxes, Declarative and Scripted Pipeline
Jenkinsfile
除了直接在网页上编写Pipeline自动化流程。我们也可以指定Jenkinsfile文件作为编写Pipeline的地方。
为什么需要Jenkinsfile?
主要还是为了放入版本管理,方便所有人可视化看到自动化流程代码。
e.g.
1 | #!groovy |
Note:
- 指定使用版本管理后,Jenkinsfile必须放到版本管理里才能找到。
- Jenkinsfile必需放到前面设置的本机相对路径下才能找到。
Problems
- 构建参数一旦通过代码指定添加后,代码删除了依然存在
- No valid crumb was included in the request
Solutions:
- 通过Pipeline -> Setting的UI界面手动删除参数
- 在系统管理 –> Configure Global Security
取消“防止跨站点请求伪造(Prevent Cross Site Request Forgery exploits)”的勾选。
Tools
Pipeline Tools
Snippet Generator
这是一个很有用帮助快速编写Pipeline的工具,他可以帮助我们把我们熟悉的自动化脚本转换成Pipeline格式的语句,也可以快速生成一些特定功能的脚本(比如邮件功能等)。(Jenkins提供)
Email Plugin
利用现有的SMTP(腾讯,网易等)服务进行搭建邮件提醒,详情参见如下:
Jenkins——应用篇——插件使用——Mailer Plugin
Jenkins自带Email配置如下:
Manage Jenkins -> Configure System -> E-mail Notification
Jenkins自带的Mailer提供的功能很有限,为了提供更多更广的功能,这里我们需要用到Jenkins Email Extension Plugin
Jenkins进阶系列之——01使用email-ext替换Jenkins的默认邮件通知
Email Extension Plugin配置详情参见如下:
Manage Jenkins -> Configure System -> Extended E-mail Notification
针对workspace自定义邮件内容配置如下:
最终收到Email提醒:
Unity3D Plugin
管理插件->Unity3d Plugin
Unity本身是支持从命令行启动U3D,执行Editor特定方法的。
但Unity3D Plugin是一个针对Jenkins集成Unity命令行的插件,可以帮助我们直接在Jenkins上编写U3D命令,对于Jenkins更加友好。
好处如下:
- Log file redirection(Log重定位到Jenkins界面)
- Distributed builds(分布式编译)
Unity3D Plugin实战配置
- Configure Unity Installation Path
System Setting -> Global Tool Configuration - 编写Unity下可通过命令行调用的代码
1 | using UnityEngine; |
- 配置Unity命令行运行启动以及参数
从上面可以看出我们成功的配置了Jenkins以及对于Unity打包方法的调用(在这一步我们可以做很多我们自己对于Unity打包的流程设置,资源打包或者其他的预处理等) - 编写完整的打包设置以及相关预处理代码
待续…….
接下来是为了在IOS进行Jenkins自动化打包而设置的步骤 - 在IOS搭配SmartSVN拉VisualSVN上的文件(Windows上用TortoiseSVN作为SVN客户端即可)
- 在IOS上配置Jenkins(和Windows上类似,需要下载Java支持Jenkins运行)
这里讲几个配置搭建Mac OSX的Jenkins时遇到的坑:- 配置Unity插件Unity安装路径问题
Windows上是到Editor上一层即可。IOS是到Unity.app这一层(Unity.app(e.g. /Applications/Unity/Unity.app/)在命令行里可以往里访问) - 指定IOS Subversion URL(e.g. https://192.168.1.3/svn/***)时显示无法访问或者不正确的credential(这里是因为默认的Mac SVN版本过低需要更新Mac OSX自带的SVN)
- 更新Mac OSX自带SVN时在添加新装的SVN到环境变量里后依然显示是老版的SVN
在~/目录下touch .bash_profile(创建.bash_profile)
然后添加环境变量路径export PATH=”/opt/subversion/bin;$PATH”
使其环境变量路径设置生效source .bash_profile
查看当前SVN版本svn —version
如果上一步依然显示是旧版SVN且当前系统是10.11
那么我们就需要删除Mac OSX上原本的SVN以实现更新SVN的目的
查看旧版SVN路径which svn
删除旧版SVN(sudo -s rm -rf /svnpath/svn)(此时如果出现No Permission to remove,那么恭喜,你是用的10.11系统。10.11推出了SIP(System Integrity Protection)机制去防止root用户对于部分文件的操作权限限制用于防止病毒破坏或修改重要文件)
为了能够删除旧版SVN,这里我们需要进到Recover Mode去临时关闭SIP(重启电脑一直按住cmd+R,然后在terminal里执行csrutil disable,关闭成功后就可以重启电脑去删除旧版svn了)
然后将新版SVN链接到旧版SVN执行路径(sudo -s ln -s /opt/subversion/bin/svn /svnpath)
最后到Recover Mode里恢复SIP(csrutil enable) - 打包IOS时报错:_RegisterApplication(), FAILED TO establish the default connection to the WindowServer, _CGSDefaultConnection() is NULL.
这是因为Jenkins默认安装时是以Jenkins作为用户和组。开机自启动时也是以Jenkins用户和组来运行的。而Unity我是默认安装在我自己的用户apple和admin组下。所以在Jenkins需要启动Unity时应该是没有权限调用 Unity Editor 的命令行。所以我们要做的就是确保Unity和Jenkins运行在同一个User和Group下。
以下采用把Jenkins改到apple和wheel下运行以支持Unity的命令行运行。
详情参见macOS 安装配置 Jenkins 持续集成 Unity 项目指南 - 指定Custom Workspace(自定义到桌面特定目录后每次都报Failed to mkdir,这个跟第四个问题是同一个问题,默认Jenkins用户权限问题)
- 配置Unity插件Unity安装路径问题
Note:
很多文件是Unity自动生成的(比如Library目录),我们无需加入版本管理(SVN只要不加入版本管理即可)
Note:
Unity3d Plugin不支持在Pipeline里添加。
同时Unity3d Plugin只在3.4.2 to 5.0.1的版本下测试过。(经本人测试在Unity5.4.0f3的版本也能正常使用)
Jenkins从零搭建
这里的从零搭建,在借助Jenkins插件的基础上,尽量采用Pipeline编写为主,插件UI为辅的方式来实现一整套完整的Jenkins自动化。
1 | #!groovy |
脚本语言
为了快速编写一些自动化任务,我们往往需要用到脚本语言。
bat
1 | :: 关闭命令输出打印 |
这里只列举一些常用基础的,详细Windows Batch学习参考:
Batch file – Programming tutorial
Batch Script Tutorial
Shell
Windows上的bat,power shell
Linux上的shell
好处:
简单快速的编写一些系统相关的任务(比如文件复制等)
缺点:
有平台差异
在正式学习Shell之前,让我们依然从What,How,Why,When这四个问题着手:
What?
Unix shell,一种壳层与命令行界面,是UNIX操作系统下传统的用户和计算机的交互界面。第一个用户直接输入命令来执行各种各样的任务。
第一个Unix shell是由肯·汤普逊,仿效Multic上的shell所实现出来,称为sh。
后续出了其他的Shell:
上面的几个Shell都可以看作是后续发展功能越来越强大的Shell解析器,至于具体分别包含些什么功能就不在本文讨论的范围内了。这里我们主要以bash和shell作为解析器来学习编写shell脚本。
可以看出Shell脚本是被当做脚本语言来解释执行,通过调用系统内核的一些工具来实现特定功能任务的。
Why?
Shell并不适合编写复杂的程序任务,因为他只提供了一些比较基础的工具,并且不具备面向对象编程等高级语言的特性。
既然如此那我们为何还要坚持使用Shell了?为何不直接选择Python,Ruby,Perl这些相对高级一点的解释性语言了?
理论上是可以的,但Shell属于原生就具备提供的工具,可以很快捷的编写出一些看似简单但却方便的工具脚本。即使Python可以实现,但针对特定的功能可能没有Shell来的那么快捷方便,根据需求选择合适的脚本语言也是很重要的。后续我会结合Python夸平台的特性,使用Python结合Shell编写一些自动化相关的工具。
Note:
Shell跟操作系统紧密相关,原本并非跨系统平台的,但通过移植很多shell具备了跨系统平台的能力(Windows上通过Cygwin与MinGW可以模拟执行Unix Shell)。
When?
那么什么时候适合用Shell了?从前面三个问题不难看出,Shell只适合用于一些不复杂的功能任务里,无论是语言特性还是跨平台都没有Python那些高级语言支持的好。如果需要实现复杂的且跨平台,需要高级语言特性(面向对象等)时,不应该考虑Shell而是Python,Perl,Ruby这些。
Note:
这里所说的shell和Window的batch并不是同一个东西。
bash
- 指定解析器
1 | #!/bin/bash |
#!是two-byte的magic number
表示这个文本是executable shell script,后面紧跟的/bin/bash表示shell解析器是用的bash
- 输出打印
学程序,最初开始的地方肯定是Hello World。
在bash里打印输出是通过echo指令。
1 | #!/bin/bash |
- 特殊符号
- 井号(#) — 注释符号
1 | # Proper header for a Bash script(这一行#号开头表示注释) |
- ; — 命令分隔符(允许同一行多个指令)
1 | #! /bin.bash |
![CommandSeparator](/img/Bash/CommandSeparator.png)
- ;; — 跳出case语句
1 | #! /bin/bash |
![TerminateCommand](/img/Bash/TerminateCommand.png)
- .
- 表示文件是隐藏的
1 | #! /bin/bash |
![HidenProfileCommand](/img/Bash/HidenProfileCommand.png)
- 表示当前目录
1 | pwd |
![CurrentDirectoryCommand](/img/Bash/CurrentDirectoryCommand.png)
- 正则里面表示匹配单个字母
- “” - 字符串(保留大部分特殊符号)
- ‘’ - 字符串(保留所有特殊符号)
- ,
- \ - 反斜杠,忽略特殊符号
1 | #! /bin/bash |
![Backslash](/img/Bash/Backslash.png)
- / - 文件路径分隔符
- : - 相当于内置true
1 | while : |
![ColonOperator](/img/Bash/ColonOperator.png)
- ! - 取反
- 星号(*) - 通配符或者乘法
- ? - 三目运算符或者表示测试条件
- $
- $ 变量取值符号
- $? 退出状态码
- $$ 进程号
1 | #! /bin/bash |
![VariableSubstitution](/img/Bash/VariableSubstitution.png)
&> >& >> < <>
&> 重定向输出到指定文件
<> 文件读取
1 | #! /bin/bash |
![RedirectionCommand](/img/Bash/RedirectionCommand.png)
- ~ ~+ - home目录和当前目录
1 | echo ~ |
![FolderCommands](/img/Bash/FolderCommands.png)
- ` - 命令执行符号(可以用于快速执行命令并将结果复制)
1 | Date=`date +%Y%m%d%H%M%S` |
![CommandsSubstitution](/img/Bash/CommandsSubstitution.png)
- Shell小知识
$0 - $9
$0表示Shell文件名
$1-$9表示Shell的第一个到第九个参数ls -l
查看文件详细信息(比如读写权限等)
具体如何理解最前面的权限信息,参考第六章、Linux 的文件权限与目录配置chmod
修改文件权限cd
切换目录pwd or ~+
当前所在目录echo
输出信息exit
退出shell$?
前一段shell的返回输出值$ or ${}
去变量值\
多行shell支持$SHELL
从当前Shell执行结束的地方打开一个新的terminal窗口(能保持之前所有的输出信息都在)
待续……
Python(严格意义上不算脚本语言)
好处:
- 跨平台
- 解释性语言,开发方便快速
- 库丰富
待续……
IOS自动化打包
IOS打包准备
Apple Account(发布到IOS设备上需要)
任何账号都可以发布到自己的设备测试,但是如果要使用GC or In-App Purchases或者发布到App Store的话需要注册Apple Developer Program。Xcode(up-to-date version)
因为Xcode是Mac上的软件,所以这里需要Mac电脑或者是黑苹果。(开发所需的SDK,IDE套装都在这)Adding your Apple ID to Xcode
Open Xcode -> Xcode -> Preferences -> Account ->在开发之前,Mac需要获得IOS Certificartes(用于对Mac开发授权,程序签名等)
登陆Apple Developer Program -> Certificates ,identifiers & Profiles -> Certificate Signing Request
Create CSR(Certificate Signing Request):- Folder -> Utilities Folder -> Keychain Access
- Keychain Access -> Certificate Assistant -> Request a Certificate from a Certificate Authority -> 填完内容存储到本地
CSR里包含了public key和private key。
当CSR创建以后,需要使用CSR去请求一个Certificate: - 上传CSR
- 下载Certificate
- 运行安装Certificate
安装Certificate后public和private key pair就生成了(在Keychain Access下可以查看)而我们的应用程序签名是使用私钥来签名用公钥来进行验证, 而苹果生成的Certificate 只包含了公钥,当你用自己的私钥签名后,苹果会用公钥来进行验证,确保是你自己对程序签名而不是别人冒充的
通过导出共享公钥和私钥,可以实现共同开发(Mac开发授权,程序签名等)。
设置App ID(相当于Android包名,用于识别App)
App ID包含以下组成部分:- Prefix — 作为Team ID
- Suffix — 作为Build ID的搜索字符串(可指定通配符)
- AppServices — 指定包含的Service(比如Game Center, IAP, iCloud等服务),只有指定了这些,使用包含了此APP ID的Provision Profile才能使用特定服务
添加设备列表(只有被添加了的设备列表才能用于安装和测试程序)
需要通过Itunes查看UDID,然后添加到设备列表。用上述我们创建的Certificate, Apple ID, Devices List等生成我们的Provision Profile(Unity Cloud Build的时候需要指定)
不同的Provision Profile有不同的用处,比如iPhone Developer证书用于测试设备上运行,iPhone Distribution证书用于提交应用到App Store。
让我们来理解一些相关概念,下文引用至IOS开发 证书总结
Identifier:
顾名思义App ID(application id, not apple id), 对于你的一个或者一组app他们的唯一标识, 这个App ID跟你Xcode中的Targets ——-> General——-> Identity中的Bundle Identifier是匹配的,(其余的那些推送服务啊什么的都是配置在APP ID下面的) 如下图:Provisioning Profile
一个Provisioning Profile包含了上述所有内容 Certificate && App ID && Device, 这个Provisioning Profile文件会在打包时嵌入到.ipa的包里,如下图:所以一台设备上运行应用程序的过程如下(以Developer Provisioning Profile为例):
1 检查app 的 bunld ID 是否 matches Provisioning Profile 的 App ID
2 检查 app 的 entitements 是否 matches Provisioning Profile 的 entitements
3 用Certificate来验证签名签名
4 检查此设备的UDID是否存在于 Provisioning Profiles中 (仅在 非发布证书中)如何创建?
在 Provisioning Profiles 中点加号,然后依次选择App ID, Certificate, Devices(development),再指定名称,最后下载, 双击则安装到Xcode中Xcode中的配置
Project && Target 的 build settings 中搜索Code sign…
然后分别选好对应的证书,如果选择列表中没有刚才创建的证书可以双击直接复制名字上去关于推送服务
基于上面的操作,如果需要推送服务我们还需要申请一个推送证书
依次进入 Certificates —>Production —>Apple Push Notification service SSL (Production)
然后选择需要推送服务的App ID
再选择前面创建的.cerSigningRequest文件
最后点击generated生成推送证书
IOS开发流程大致如下:
XUPorter or Unity API(PBXFroject)
PBXFroject是Unity 5.X版本加进来的。因为5.X以前没有关于XCode自动化修改的相关接口,所以以前的版本用的都是XUPoter这个第三方插件工具来实现自动化修改info.plist文件,自动添加library之类的功能。
本人只使用过XUPoter还没详细使用PBXProject,但XUPoter的作者在Unity 5.X开始已经不在更新支持了,因为有了PBXProject,所以可以这样说,Unity 5.X版本开始可以直接使用Unity 5.X不需要再使用XUPoter了。
XUPoter
这里直接给出作者工具链接,就不详细讲解如何集成使用了,具体参考官方作者网站。
onevcat/XUPorter
PBXProject
对IOS的打包后的XCode工程做后处理,我们需要在代码里实现IPostProcessBuild接口的OnPostProcessBuild方法。
XcodePostProcess.cs
1 | using UnityEngine; |
这里就不一一截Mac对应的图了,示例代码对XCode的各种参数设置都进行了修改,注释也很清楚了,具体详细的使用,请参考官网API解释。
IOS自动化签包
Xcodebuild是XCode上编译Xcode工程的工具。
所以接下来我们主要是要学习的是使用Xcodebuild去编写自动化签包的工具。
学习XCode Project项目里的一些相关概念。
一下概念来源iOS系统提供开发环境下命令行编译工具:xcodebuild:
- Workspace:简单来说,Workspace就是一个容器,在该容器中可以存放多个你创建的Xcode Project, 以及其他的项目中需要使用到的文件。
使用Workspace的好处有:- 扩展项目的可视域,即可以在多个项目之间跳转,重构,一个项目可以使用另一个项目的输出。Workspace会负责各个Project之间提供各种相互依赖的关系;
- 多个项目之间共享Build目录。
- Project:指一个项目,该项目会负责管理生成一个或者多个软件产品的全部文件和配置,一个Project可以包含多个Target。
- Target:一个Target是指在一个Project中构建的一个产品,它包含了构建该产品的所有文件,以及如何构建该产品的配置。
- Scheme:一个定义好构建过程的Target成为一个Scheme。可在Scheme中定义的Target的构建过程有:Build/Run/Test/Profile/Analyze/Archive
- BuildSetting:配置产品的Build设置,比方说,使用哪个Architectures?使用哪个版本的SDK?。在Xcode Project中,有Project级别的Build Setting,也有Target级别的Build Setting。Build一个产品时一定是针对某个Target的,因此,XCode中总是优先选择Target的Build Setting,如果Target没有配置,则会使用Project的Build Setting。
了解了XCode Project中的一些概念,让我们看看Xcodebuild到底是什么样的工具了?
xcodebuild is a command-line tool that allows you to perform build, query, analyze, test, and archive operations on your Xcode projects and workspaces from the command line. It operates on one or more targets contained in your project, or a scheme contained in your project or workspace.
如果想查看xcodebuild的详细说明,我们可以通过命令行输入:man xcodebuild查看即可:
首先以XcodeProject为例,我们来看看上面的概念在实际操作过程中对应的东西:
从上面可以看出,我们的Demo Xcode Project是没有workspace的,只有一个叫做Unity-iPhone.xcodeproj的Xcode工程文件,而这个文件对应的就是我们前面提到的Project的概念。
如果我们想查看Xcode Project里面的相关schemes或者target信息,我们可以通过命令行切换到Xcode Project目录下然后输入xcodebuild -list -project *.xcodeproj命令来查看:
从上面的信息我们可以看到,我们的Unity-iPhone.xcodeproj项目里有两个Targets分别为:Unity-iPhone和Unity-iPhone Tests以及一个Schemes:Unity-iPhone。这些都分别对应了我们前面最初所了解的相关Xcode Project的概念。
如果想要查看Xcode Project的详细Build Setting设置信息,我们可以通过输入xcodebuild -showBuildSettings来查看:
-showBuildSettings有不少东西,很多概念需要对比着Xcode工程里的设置来看,这里暂时不深究每一个代表什么意思。
了解了Workspace,Project,Target,Scheme,BuildSetting等等概念以及如何通过xcodebuild工具查看Xcode工程相关信息后,接下来我们看一下xcodebuild是如何编译打包导出IPA的。
这里参考网上,我发现Xcode9以后有两种方式来实现自动化打包。
- Automatic
- Manual
这里我先以Manual的形式来学习打包,后续再学习了解Automatic的形式打包。
首先我们来看看官方对xcodebuild工具的介绍:
xcodebuild is a command-line tool that allows you to perform build, query, analyze, test, and archive operations on your Xcode projects and workspaces from the command line.
可以看出xcodebuild正式苹果官方给出的通过命令行触发打包编译导出一系列操作的工具。
具体想知道xcodebuild的详细使用介绍,可以在shell里输入man xcodebuild查看即可:
Manual:
手动打包之前,我们要用到下面几个比较重要的xcodebuild命令参数:
- clean — Remove build products and intermediate files from the build root(SYMROOT)(清楚通过build触发编译的所有中间文件)
- build — Build the target in the build root(SYMROOT). This is the default action, and is used if no action is given.(build指定target)
- archive — Archive a scheme from the build root(SYMROOT). This requires specifying a scheme.(打包指定scheme)
- exportArchive — Specifies that an archive should be exported. Requires -archivePath, -exportPath, and -exportOptionsPlist. Cannot be passed along with an action.(指定Archive文件导出IPA)
下面以工作中完整的命令行编译打包导出IPA为例来讲解学习(敏感信息中文代替):
1 | #! /bin/bash |
这里针对上面的自动化签包脚本,我们需要理解几个关键概念:
- 包名 — 我们平时说的包名,Unity里平台设置那里设置的包名
Xcode里显示参考下图:
- 证书名字 — IOS开发打包需要的证书文件(比如:Development,Distribution证书)
因为Apple Developer Account最近刚到期,无法截后台账号的图,这里只放一张Keychain里面显示已经安装在本地的Certificate图:
证书名字通过右键对应Certificate后选择Get Info可查看:
- 描述文件 — 是指后台指定了Certificate,Apple Id, Device List等信息的描述文件
如果想详细查看里面的信息,可以通过下面这个命令:
1 | security cmd -D -i *.mobileprovision |
这里面就包含了很多信息,这里我们暂时需要通过这个找到描述文件的名字:
- IOS最低版本支持 — 这个是对应Xcode里设置Deployment Target的那个参数,表示打包支持的最低IOS版本
- 签名配置文件 — 关于导出IPA时的签名信息以及相关参数等的配置文件
让我们看下里面的详细信息:
1 | <?xml version="1.0" encoding="UTF-8"?> |
可以看到签名配置文件里面指定了导出类型(app-store or development等),证书名以及包名,描述文件信息等信息。
那么这个配置文件哪里来的了?
手动Archive后,我们会在*.ipa的同层文件目录下得到一个叫ExportOption.plist的文件,这个就是那个配置文件。
Note:
如果我们的程序开启了苹果相关的服务,比如Apple Wallet等,那这些服务会以参数的信息显示在上面的配置文件里,如果后台证书配置了使用特定服务,但该配置文件里没有,就会提示特定字段信息对不上或者遗漏而报错。
可以看出通过上面的自动化,我们可以命令行指定以下内容:
- 包名
- 证书
- 描述文件
- IOS最低支持版本号
- 签名证书
接下来我们看看xcodebuild编译里是如何指定这些信息并成功导出IPA的:
- 清理工程
1 | xcodebuild clean \ # 指定了清理工程 |
- 编译打包
1 | xcodebuild -project Unity-iPhone.xcodeproj \ # 指定打包哪个project |
- 导出IPA
1 | xcodebuild -exportArchive \ # 指定导出IPA |
上面的注释已经很详细了,这里就不在详细讲解了。
通过archive命令,我们得到了一个.xcarchive的文件。
通过这个.xcarchive文件,我们可以通过指定签名配置文件导出我们想要的IPA文件。
Automatic:
待续……
References
Jenkins Part
Groovy
Uniy3d Plugin
Jenkins——应用篇——插件使用——Mailer Plugin
Jenkins进阶系列之——01使用email-ext替换Jenkins的默认邮件通知
macOS 安装配置 Jenkins 持续集成 Unity 项目指南
MAC EI Capitan上更新系统自带SVN版本(关闭SIP方能sudo rm)
About System Integrity Protection on your Mac
Email-ext plugin
Shell Part
Unix shell
Shell脚本
Advanced Bash-Scripting Guide
Xcodebuild Part
Xcode 9 最新 最准确 的自动化打包
iOS系统提供开发环境下命令行编译工具:xcodebuild
Building from the Command Line with Xcode FAQ
Build settings reference