关于 iOS 批量打包的总结

如果你曾经试过做多 target 的项目,到了测试人员要测试包的时候,你就会明白什么叫“生不如死”。虽然 Xcode 打包很方便,但是当你机械重复打 N 次包的时候,就会觉得这纯粹是浪费时间的工作。所以这时候自动化打包就显得尤为重要(其实就算只有一个 target,就算使用 Xcode 打包很方便,也应该构建自动化打包,因为你可以节省大量时间)。

构建自动化打包脚本

xcodebuild

使用 xcodebuild -h 来看看 xcodebuild 到底是干啥的

这里我只截取了 usage 部分,option 部分太多没有截取。

这里介绍几条毕竟常用的命令

1. xcodebuild -list …

xcodebuild -list [[-project ]|[-workspace ]] [-json]

usage: 输出 project 中的 targets 和 configurations,或者 workspace 中 schemes。
-project-workspace 是输出指定内容,不输入默认输出当前目录下。-json 是以 json 格式输出。

example:

2. xcodebuild -project …

xcodebuild [-project ] [[-target ]...|-alltargets] [-configuration ] [-arch ]... [-sdk [|]] [-showBuildSettings] [=]... []...

usage:

-project: 指定 project 名字,默认首个 project。

-target: 指定对应的 target ,默认首个 target。

-configuration: 选择Debug 或 Release,默认 Release,当然如果你有自定义的配置的,就应该选你配置的,上面 -list 中有输出。

-showBuildSettings: 显示工程的配置。

=: 修改工程的配置文件。

buildaction ... : 如下,默认为 build

example:

  • $ xcodebuild -project 你的项目名字.xcodeproj -target 你的 target 名字 -configuration release

这行命令表示编译 xx.xcodeproj 的 xx target。在 terminal 中会看到编译过程,如果成功最后会输出 ** BUILD SUCCEEDED **。最后会在当前目录下生成 build/Release-iphoneos/xx.app

  • $ xcodebuild -project 你的项目名字.xcodeproj -target 你的 target 名字 -configuration release -showBuildSettings

这行命令使用 -showBuildSettings 是不会 build 项目的,只是输出工程的配置。这里输出的的内容有(内容过多,只截取部分)

如果要修改配置文件,就直接最命令最后加上你要修改的内容。
例如在这行命令最后加上指定证书

  • $ xcodebuild -project 你的项目名字.xcodeproj -target 你的 target 名字 -configuration release PROVISIONING_PROFILE="你证书的id"

其中的字段是上面 -showBuildSettings 显示的字段,也可以看官网介绍

3. xcodebuild -workspace …

xcodebuild -workspace -scheme [-destination ]... [-configuration ] [-arch ]... [-sdk [|]] [-showBuildSettings] [=]... []...

除了 workspace 和 scheme 之外其余选项都和上条命令相同。

-workspace: 指定 workspace 名字,默认首个 workspace

-scheme: 指定对应的 scheme ,默认首个 scheme

4 . xcodebuild -exportArchive …

这里顺便介绍一下 archive 命令,因为在下面使用 PackageApplication 会出一个警告说推荐使用 -exportArchive。所以我们就来尝试一下使用 archive 来生成 app。

首先使用一下命令来生成 .xcarchive 文件
xcodebuild archive -workspace xx.xcworkspace -scheme xx -archivePath xx.xcarchive
可以看出添加上 archive 命令和最后加入 -archivePath 生成archivePath的路径即可。
然后该路径下会生成一个 xx.archivePath,里面包括三个文件,xx.app.dsym文件(可用于bugly等监控bug的平台),info.plist(保存打包的一些信息),还有我们的 xx.app 文件。

其次使用 -exportArchive 生成 ipa 包

xcodebuild -exportArchive -archivePath xx.xcarchive -exportPath xx -exportFormat ipa

-archivePath: xx.archivePath 的路径

-exportPath: 输出路径

-exportFormat: 生成类型,这里选择我们需要的 ipa

这样就利用我们的 xcodebuild 命令来生成 ipa 包

xcrun

这里也使用 xcrun 来生成 ipa 包即可

xcrun -sdk iphoneos PackageApplication build/Release-iphoneos/xx.app -o ~/Desktop/xx.ipa

但是,在 macos10.12 和 Xcode8 的环境下会出现一个警告

warning: PackageApplication is deprecated, use xcodebuild -exportArchive instead.

说明 PackageApplication 已经被弃用了。

不过其实这一步可以几乎等价于将 xx.app 放入一个 payload 的文件夹下然后压缩文件夹为 xx.ipa,当然这样做缺失一些信息,不过并不影响程序的运行。

初步小结

综上,我们有两种方法来生成我们需要的 ipa 包。

  1. 使用 xcodebuild 命令来编译我们的项目生成 app,然后再用 xcrun 将 app 转 ipa。
  2. 使用 xcodebuild archive 命令来直接生成我们需要的 ipa。

虽然现在网上几乎都是使用 xcodebuild + xcrun 来来生成 ipa 包,不过既然官方说 PackageApplication is deprecated,那还是推荐使用第二种方法,一步到位。

自动化打包正式开始

这里从我工作室的一个项目切入,这个项目需要最终生成 18 个 ipa 包,但是他们几乎是共用一套代码的,不同的地方在于bundleName/bundleDisplayName/bundleid 等,以及一些资源文件的不同,例如 icon 等。所以可想而知如果选择手动打包的痛苦,并且当你打包到一半发现某个地方错了要重新打包 ……

这里说一下自动化打包1.0解决思路:

  1. 使用命令 defaults write 来修改项目中的 plist 文件,来达到修改 bundleName/bundleDisplayName/bundleid… 的目的。
  2. 使用命令 cp 来替换资源文件。
  3. 使用 xcodebuild -workspace .. 编译出 app 包。
  4. 使用 xcrun ... 生成 ipa 。

这是我最开始想到的思路,最终运行时间大概为每个包2.5m(时间主要浪费在编译),然后一套下来也要半个多小时。虽然比起手动打快了不少,但还是太慢了。毕竟自动化的目的不仅仅是自动,还要速度。

既然问题出在编译上,那我的思路就往编译一次多次使用这个方向上面思考。然后想到了既然只是资源文件和plist的不同,没有涉及到代码的更换(不过这个项目后期不同 app 会执行不同一套代码,不过也有解决办法),这里就出现了自动化打包2.0的版本。

  1. 使用 xcodebuild -workspace .. 编译出 app 包。
  2. 使用命令 defaults write 来修改项目中的 plist 文件,来达到修改 bundleName/bundleDisplayName/bundleid… 的目的。
  3. 使用命令 cp 来替换资源文件。
  4. 重签名 codesign -f -s "iPhone Distribution: xx co., LTD" --entitlements $Entitlements $ipaPath/Payload/YouXiaoYun.app
  5. 使用 xcrun ... 生成 ipa 。

和1.0大致相似,不过并不是每次生成 ipa 都需要编译一次。而是编译一次,然后直接修改 app 下内容,不过这里会出现签名错误的问题,因为在编译的最后会用证书帮 app 签名,如果你直接替换资源然后就生成 ipa 的话会导致 ipa 无法安装。

那这时候神奇的重签名技术就出来(重签名用在正途上的真少见…hhhh,关于重签名的文章 google 一下就会很多),使用 codesign 命令就可以帮修改过资源的 app 重签名。
最终使用2.0的时间基本是在5-6分钟左右。果然能机器完成的工作绝对不要手动完成,从半天到30分钟到最后的6分钟,节省下来的时间可以让你学习到更多。

上面说到如果不同 app 间会用到不同的代码。例如 app A 里面的 title 叫 A 部门,app B 里面 title 又叫 B 部门,这样就不会通过命令行直接修改到代码,不过我想到的是维护一个 plist 文件,plist 文件可以这样设计的,每个不同 app 的 bundleName 都设置字典的键,然后字典下就可以是你自定义的内容。然后每次启动 app 就根据 bundleName 来寻找对应的字典,然后 title 就赋值为 plist 下 title 的值。如果不同代码就根据 code1 里面的值来 switch 不同的代码。

11228408-e1aa7e98b1d1edb6

最终代码

以下是完整的脚本文件,部分信息需要自己替换。
以下脚本适用于一次打 N 个包,适用情况:

  1. 可以替换 bundle 信息
  2. 替换音频图片资源
  3. 可以执行不同代码
  4. 生成相应的plist文件
  5. 上传到蒲公英分发平台

当然也可以打一个包,适当删除某些代码即可。

打赏支持我写出更多好文章,谢谢!

打赏作者

打赏支持我写出更多好文章,谢谢!

任选一种支付方式

1 1 收藏 2 评论

关于作者:Tsui YuenHong

简介还没来得及写 :) 个人主页 · 我的文章 · 1 ·   

相关文章

可能感兴趣的话题



直接登录
最新评论
跳到底部
返回顶部