zoukankan      html  css  js  c++  java
  • 关于 iOS 批量打包的总结

     

    关于 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. 上传到蒲公英分发平台

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

  • 相关阅读:
    turtle绘制彩色螺旋线
    turtle 画一朵花
    Spark Streaming+Kafka提交offset实现有且仅有一次(exactly-once)
    利用Spark实现Oracle到Hive的历史数据同步
    spark-submit提交Spark Streamming+Kafka程序
    SparkStreaming+Kafka 实现统计基于缓存的实时uv
    SparkStreaming+Kafka 实现基于缓存的实时wordcount
    基于OGG的Oracle与Hadoop集群准实时同步介绍
    Spark Streaming连接Kafka入门教程
    spark连接hive(spark-shell和eclipse两种方式)
  • 原文地址:https://www.cnblogs.com/oc-bowen/p/6109166.html
Copyright © 2011-2022 走看看