通过Shell一键修改target的版本号

脚本的由来

随着项目的发展,目前我们项目已经有5个target了,一个主target,2个Today Widget的target,2个Apple Watch的target。这些target的版本号必须一模一样才能编译通过,也就是Info.plist中的CFBundleShortVersionString。每次版本迭代的时候都要手动一个一个改一点,实在太麻烦,而且对于一个程序员,怎么能忍这种很机械的操作!遂,鼓动个脚本一劳永逸~

脚本的实现思路

主要要解决2个问题,一个是怎么拿到Info.plist的路径,一个是怎么区分要改哪个渠道的版本号,我们有App Store包、企业包、两个马甲版的包…

对于Info.plist的路径,我一开始想的遍历整个项目的目录文件查找,细想后发现这个操作起来太麻烦,而且又有Pods等,会起到干扰,很难判断哪些才是真正target对应的plist。如果直接把plist的路径都放在脚本中,也不是很好,因为这个路径可能因为项目重新进行整理变掉,这个时候还要再来改脚本的内容。后来想到Xcode Build Settings中的内容应该也会以某种文件形式存在,google了一下,发现了xcodebuild -showBuildSettings这个命令可以把指定target的Build Settings中所有的内容都打印出来。仔细一找,plist的路径在PRODUCT_SETTINGS_PATH这个key里。这就好办了,用grep "PRODUCT_SETTINGS_PATH"可以只拿这一行,再用字符串处理把路径拿到。

对于第2个问题,解决的过程中走了一些弯路,直接说一下我最后的处理方式吧,通过Bundle Id来定位是要改哪个渠道的版本号。通过xcodebuild -showBuildSettings一样可以拿到Bundle Id,那用grep -E "PRODUCT_SETTINGS_PATH|PRODUCT_BUNDLE_IDENTIFIER"就可以把指定target的plist路径和Bundle Id都拿到了,再指定alltargets可以指定获取全部的了,最终的命令如下:

1
xcodebuild -project $projectName -alltargets -showBuildSettings | grep -E "PRODUCT_SETTINGS_PATH|PRODUCT_BUNDLE_IDENTIFIER"

运行后得到的结果如下:

1
2
3
4
5
6
7
PRODUCT_BUNDLE_IDENTIFIER = bundle id
PRODUCT_SETTINGS_PATH = plist path
PRODUCT_BUNDLE_IDENTIFIER = bundle id
PRODUCT_SETTINGS_PATH = plist path
PRODUCT_BUNDLE_IDENTIFIER = bundle id
PRODUCT_SETTINGS_PATH = plist path
...

把上面的结果,分割成数组,比较2*i位置的Bundle Id是不是想要的,如果是,则取2*i+1的plist路径,然后修改CFBundleShortVersionString即可。Bundle Id要直接配置在脚本中,只要配置主target的就好,比如主target的Bundle Idcom.zn.abc,那其他的target的Bundle Id的格式一定是这样的com.zn.abc.*

脚本的地址:https://github.com/shinancao/Shell-Plist-Version

脚本的使用

  1. 在脚本中配置你工程的project的名字,还有各渠道的主target的Bundle Id
  2. 将脚本放在project所在的文件夹中。
  3. 具体的使用:
1
2
3
4
5
6
7
8
9
10
11
12
使用说明:
修改指定target组的版本号
plist-version -i <index of bundleId array> -v <version num>
修改全部target的版本号
plist-version -a -v <version num>

参数说明:
-a 指定修改全部target的版本号
-s 展示配置在脚本中的target
-h 查看命令的使用
-v 指定的版本号
-i 指定build id对应的索引