最近公司想要整合打包测试,打包上线的流程。想要实现iOS快速的出包。
我们公司采用的是jenkins+fir.实现的原理是自动到Git仓库中拉取最新的代码,然后下载到指定的一台苹果电脑上,打完包之后再上传到服务端供测试和运维人员进行下载使用。
因为我们公司关于jenkins是Java研发在弄,关于这个我就不进行赘述。
1.公司项目情况分析:
--我们公司一共有三款产品:xxx金服,xxx金服专业版,xxx金服活动版。这三款产品共用相同代码,但是图片素材是不一样的,所以是在同一个project中的。
--打包环境有:develop(开发) test(测试) production(线上)local(本地)
--现在我们来整理一下:三种产品,四种环境。这代表了有12种情况需要通过命令行来区分。
2.解决的办法:
--解决的办法:通过不同的target来区分不同的版本,通过不同的configuration来区分不同的环境配置和key。
--xcodebuild的命令可以进行Xcode命令行打包,相关命令可以再终端输入man xcodebuild查看,或是直接看苹果官方文档点我点我。
--xcodebuild archive 是打包命令,其中有一个参数是-configuration 它对应参数如下:
--我们可以通过指定-configuration 和-scheme的参数来对应执行不同的环境和版本。初始默认状况configuration只有Debug和Release两种情况。我们可以通过添加.xcconfig文件来添加不同的configuration。
3.集成过程:
3.1.创建多个target,优化图片资源的引用:------
--之前我们公司三款产品是共用一套代码,共用一个target,我是在每次打包的时候手动修改图片素材还有bundle ID,displayName等等。这样人工成本太大,而且易出错。并且对于命令行打包三个不同的版本更是很难实现,因此我使用了三个Target分别对应三个项目。如下图复制另外两个target,然后将使用的素材素材库更改。
--但这样出现了一个问题,就是三套图片我都需要放在Assets.xcassets文件中,然后代码内部判断bundle ID来选择不同的素材。这样导致的问题就是导出来的ipa包从原来的29M变为了45M.因为achive的时候链接的.xcassets素材过多。
--现创建三个版本对应的Assets.xcassets文件,如图:
--三个版本相同的素材放在Assets.xcassets中,不同的放在对应的文件中,Normal(标准版),Pro(专业版),Nat(活动版)
--在三个版本target中,在copy bundle resource中只添加对应的.xcassets文件和Assets.xcassets就可以了。
--再次编译你就会发现ipa又变回了之前的大小。同理配置其余两个target。
3.2.增加15个.xcconfig文件--------------
--一共我们需要1.Debug 2.Release 3.Adhoc 4.Local 5.Test 五种configuration ,如图。
--根据项目情况,每个配置文件中都包含同样的 key 值,内容如下:
#include "Pods/Target Support Files/Pods-zkp/Pods-zkp.debug.xcconfig"
//网络请求baseurl
REQUEST_BASE_URL = @"http:\/\/xxxx/resource/"
AGREEMENT_BASE_URL = @"http:\/\/xxxx/resource/product/agrHtml?prdCode="
H5_BASE_URL = @"http:\/\/xxxx"
SECRET = @"xxxxxx"
CLIENTID = @"xxxxx"
//App
APPSCHEM = @"cn.com.xxx.zkp"
APPID = @"xxxxxx"
//友盟配置
UmengAppkey = @"xxxxxxxxxxxxxxxxxxx"
//百度统计
BaiduMobKey = @"xxxxxxxxxxxxxxx"
//微信
WeChatKey = @"xxxxxxxxxxxxx"
WeChatSecret = @"xxxxxxxxxxxxxxxxxxxx"
#include "../ZKPGenerator.xcconfig"
--你可在配置文件中包含其他配置文件,其中 Generator.xcconfig 文件的内容是:
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) ZKPPrefix='$(REQUEST_BASE_URL)' ZKPAgreement='$(AGREEMENT_BASE_URL)' WebViewBaseURL='$(H5_BASE_URL)' UmengAppkey='$(UmengAppkey)' WeChatKey='$(WeChatKey)' WeChatSecret='$(WeChatSecret)' BaiduMobKey='$(BaiduMobKey)' CLIENTID='$(CLIENTID)' SECRET='$(SECRET)' APPSCHEM='$(APPSCHEM)' APPID='$(APPID)'
--其作用是将配置文件中定义的常量定义成预编译宏,以便于在代码中获取。有点类似我们项目中的PCH文件 其中GCC_PREPROCESSOR_DEFINITIONS, 文档如下:
Space-separated list of option specifications. Specifies preprocessor macros in the form foo (for a simple #define) or foo=1 (for a value definition). This list is passed to the compiler through the gcc -D option when compiling precompiled headers and implementation files.
--GCC_PREPROCESSOR_DEFINITIONS 是 GCC 预编译头参数,通常我们可以在 Project 文件下的 Build
Settings 对预编译宏定义进行默认赋值。在 Xcode下的路径为 Build Settings->Apple LLVM 8.0
-Preprocessing->Preprocessor Macros
--注意事项:
1>.此处要注意域名的转译:http:\/\/xxxx/xxxx/ 不能写 为http://xxxx/xxxx/,因为默认会将http:后面的内容注释掉。
2>.但是在转译之后,在编译项目的时候会出现警告。因为xcode警告机制不能识别转译符,而且往往这种警告会有上百个,因为域名的宏所有网络请求都会用到。如下图:
3>.解决办法忽略警告。右键警告->Reveal in Log
4>.此处就是这个警告的描述,复制之后进入build setting中将该警告进行忽略
5>.在build setting中搜索other warning,将刚刚的警告标示写入并以-隔开。如下:-Wunknown-escape-sequence
-W是前缀,如果要忽略需要添加为-Wno-unknown-escape-sequence,保存,再编译,是不是发现警告就消失了
3.3.创建5种configuration--------------
--创建configuration,添加对应的5种configuration,在添加Adhoc的时候是copy自Release,其余的都是copy自Debug
--修改.xcconfig 文件里的宏要特别注意缓存,经常会出现修改之后还用的是之前的值。这个时候xcode clean是没有用的。
--解决办法:将DerivedData中的缓存删除,然后重启xcode。
--将刚刚创建好.xcconfig文件的对应添加进去
3.4.配置证书和描述文件--------------
--电脑和xcode配置对应的证书和描述文件: 至此基本就大功告成,然后对应的在开发者后台配置证书:
3.4.1.证书:
1>.开发证书
2>.发布证书
3.4.2.描述文件:
1>.开发(用来跑真机的),对应开发证书
2>.Adhoc证书(用来给测试安装测试包),对应发布证书
3>.发布证书(发布至App Store),对应发布证书
--安装好之后,xcode配置全部结束。
3.5.执行命令--------------------
3.5.1.cd到代码目录
3.5.2.开始打包
xcodebuild archive -workspace zkp.xcworkspace -configuration Adhoc -scheme zkp -archivePath zkp.xcarchive CODE_SIGN_IDENTITY="iPhone Distribution: xxxxxxxx(yyyyyyy)" PROVISIONING_PROFILE_SPECIFIER="xxxxxxx"
1>.对应的参数配置
-workspace 工程文件名(用cocopods集成的项目,没有的话 整个改为-xcodeproj zkp.xcodeproj)
-configuration 对应的环境配置,就是编译的时候执行的模式
-scheme 通过scheme指定不同的target
-archivePath 导出的.xcarchive的路径
CODE_SIGN_IDENTITY 开发证书的名称
PROVISIONING_PROFILE_SPECIFIER 描述文件的名称
3.5.3.导出ipa
xcodebuild -exportArchive -archivePath zkpPro.xcarchive -exportPath ~/Desktop/专业版 -exportFormat ipa -exportProvisioningProfile xxxxxxx
1>.对应的参数配置
-archivePath .xcarchive文件的路径
-exportPath 导出的ipa的路径
-exportProvisioningProfile 描述文件的名称(和上述保持一致)
3.5.4.总结:
--iOS在archive的时候就会进行签名,然后导出的时候再度进行签名验证,此处和Android有区别,Android打包的时候并不会进行签名,在导出的时候才会进行签名。因此iOS在打包,和导出的时候都要指定签名。
--上述命令是笔者自己整理出来的,亲测有效,有问题欢迎评论。通过这个可以不再xcode内部指定证书,因为不止一个人开发,如果其他开发人员不小心改动了,不就扯淡了嘛。
--最后xcodebuild命令行打包有个坑,在首次从仓库拉下代码的时候,在项目没有打开之前执行xcodebuild
--achive命令的时候会卡在下图的场景里。但如果是项目已经打开了则不会卡住,会achive成功。
--究其原因由于 scheme 文件不存在造成的。而scheme文件是存储在xcuserdata文件夾下,工程项目在没有打开之前xcuserdata文件下是没有内容的,打开之后才会默认生成。但是 xcodebuild 工具不会,在执行 archive 的时候会卡死。
--解决办法:
1>.选择manager scheme
2>.选择共享scheme
--之后再打包就可以了。
--至此关于CI自动化打包,关于iOS端需要配置的工作就都做完了。因为内部是多个target,前前后后遇到挺多坑的,特此总结下。