本篇主要作为前文的补充,介绍一些构建上的调整
在 《Flutter 搭建 iOS 命令行服务打包发布全保姆式流程》 里介绍过如何通过自定义配置,完成一套自己企业内部的自定义构建过程,当然也有一些建议如使用:fastlane
、jenkins
、appcenter
等等,事实上也尝试过这些平台,也在上面使用过一段时间,但是这里解释为什么不用这些平台:
- 打包机器不登录开发者账号,需要本地开发机器是 Automatic ,而打包机上使用 Manual;
- 一个项目需要支持打包时指定
mobileprovision
和bundleId
,例如 QA 和 Prod 打包后是两个不同的bundleId
,两个 ipa 可以同时存在手机上; - 自定义构建时修改某些信息;
所以基于这些,最终决定了自己构建一套 命令行的打包模式 ,大概总结是:
- 通过 PlistBuddy 在编译时修改 plist 信息;
- 生产不同的
mobileprovision
文件; - 在 Xcode 取消 automatically manage signing,选择导入 Profile 文件,然后通过 git 生成 .patch ,在打包机器上执行 git apply ;
- 通过 xcodebuild 打包构建;
- 通过 ExportOptions.plist 模版进行 xcodebuild -exportArchive 得到 ipa ;
详细流程可以看上面原文,但是这个流程其实一直有一个问题,那就是通过 git 生成 .patch 文件,每次一旦 project.pbxproj
出现变化, 就可能会导致 git apply 失败。
Xcode 作为高度 UI 化的开发工具,经常出现调整一个配置就会导致 project.pbxproj
出现大量更改的情况,所以后面开始寻找一种更为官方的方式,来实现打包时动态替换 mobileprovision
和 bundleId
。
通过对比之前的 git diff 文件,可以看到改变还是有规律的,从 Automatic 到 Manual 指定 mobile provision 文件,主要变化的部分有:
- 新增的 ProvisioningStyle 、 CODE_SIGN_IDENTITY、CODE_SIGN_STYLE 和 PROVISIONING_PROFILE_SPECIFIER 这几个更改;
- 除了 ProvisioningStyle 之外,其他更改在 debug、profile、release 配置下都规律性出现变化;
首先解释下这几个配置:
- ProvisioningStyle = Manual 表示了打包时采用手动签名的模式;
- CODE_SIGN_IDENTITY 表示打包模式的 Inentity;
- CODE_SIGN_STYLE 表示对应打包模式下的签名模式;
- PROVISIONING_PROFILE_SPECIFIER 表示指定的 mobileprovision 的 name;
- DEVELOPEMNT_TEAM 就是你开发者账号所在的 team Id;
所以到这里,可以考虑在打包时通过直接通过系统 sed
命令来实现动态调整,事实上 网上 还真有类似的建议,比如:
sed -i ‘’ ‘s/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/’ MyProj.xcodeproj/project.pbxproj
sed -i ‘’ “s/DevelopmentTeam = ${DevelopmentTeamID};/DevelopmentTeam = \”\”;/” MyProj.xcodeproj/project.pbxproj
sed -i ‘’ “s/DEVELOPMENT_TEAM = ${DevelopmentTeamID};/DEVELOPMENT_TEAM = \”${TEAM_ID}\”;/” MyProj.xcodeproj/project.pbxproj
从这段脚本可以看到,就是通过 sed
去调整 ProvisioningStyle 和 DevelopmentTeam 等,但是这里有个问题,就是你的 project.pbxproj
不一定有 ProvisioningStyle 配置,因为如果是默认 automatically manage signing ,可能 project.pbxproj
文件下是没有这个参数。
但是 DevelopmentTeam 和 DEVELOPMENT_TEAM 一定是有,所以可以灵活变通一下,将命令改为
///改为 Manual
sed -i '' 's/DevelopmentTeam = 你的teamId;/DevelopmentTeam = 你的teamId;\nProvisioningStyle = Manual;/' ios/Runner.xcodeproj/project.pbxproj
/// option 1、改为 Manual 和指定 provision
sed -i '' 's/PRODUCT_BUNDLE_IDENTIFIER = 原来的bundleID;/PRODUCT_BUNDLE_IDENTIFIER = 需要替换的bundleId;\nCODE_SIGN_IDENTITY = "iPhone Distribution";\nCODE_SIGN_STYLE = Manual;\nPROVISIONING_PROFILE_SPECIFIER = "描述文件的name";/' ios/Runner.xcodeproj/project.pbxproj
///option 2、改为 Manual 和指定 provision,但是不需要修改 bundleId 的
sed -i '' 's/DEVELOPMENT_TEAM = 你的teamId;/DEVELOPMENT_TEAM = 你的teamId;\nCODE_SIGN_IDENTITY = "iPhone Distribution";\nCODE_SIGN_STYLE = Manual;\nPROVISIONING_PROFILE_SPECIFIER = "描述文件名字";/' ios/Runner.xcodeproj/project.pbxproj
运行后的结果就是在 DevelopmentTeam 和 DEVELOPMENT_TEAM 下添加对应所需的信息,从而达到指定 mobileprovision 和 Manual 签名的目的:
- 需要替换 bundleId 的可以使用 PRODUCT_BUNDLE_IDENTIFIER 作为替换入口;
- 不需要替换 bundleId 的可以使用 DEVELOPMENT_TEAM 作为替换入口;
最后提一句,这里构建的前提是,每次打包时 clone 一个全新的目录,构建成功后删除目录的过程,所以整个构建每次都是全新的,如果对于这部分内容感兴趣的,还可以详细参考以下资料:
《Flutter 搭建 iOS 命令行服务打包发布全保姆式流程》
最后不得不吐槽一句, Xcode 和 iOS 的在构建打包部分的资料真的少,这大概也是因为 Xcode 的高度 UI 化的贡献吧~