Flutter iOS 独立打包服务搭建指南
在以前的《Android 和 iOS 打包提交审核指南》里介绍了Flutter下打包Android和iOS的指南,不过这部分内容主要介绍的是如何在本地打包发布流程。
但事实上一般的产品发布流程,都会有专门的机器用于打包服务,「在统一干净的环境下进行打包更有利于发布的管理,避免各种本地环境差异问题」。
当然大多数时候可以直接使用第三方的CI服务,但是专门支持Flutter的第三方服务并不多,并且**「自己动手还免费」**,所以本篇主要介绍自己搭建独立打包服务的过程。
由于Android的命令打包服务比较简单,这里主要介绍配置搭建iOS下的Flutter打包和发布CI,「其实主要也是iOS的CI」。
一、参数支持
首先在iOS上很多的配置信息都是写在info.plist文件,所以一开始需要解决打包时支持动态修改info.plist的参数,这样有利于我们在输出不同环境的包配置,如:QA、Release、Dev等等。
/usr/libexec/PlistBuddy -c "Set CFBundleVersion ${CFBundleVersion}" ./Runner/Info.plist
/usr/libexec/PlistBuddy -c "Print CFBundleVersion" ./Runner/Info.plist
在Mac上其实本身就自带了满足需求的命令行工具:PlistBuddy,如上命令所示:
- 通过
Set命令可以直接动态配置plist下的版本号、code和第三方App Id等相关配置; - 通过
Print命令直接输出对应的plist信息;
二、手动配置证书
手动配置证书和mobile provision会比较麻烦,但是它可以让服务更加通用,也让你更熟悉iOS打包的流程。
- 首先通过本地钥匙串创建
CertificateSigningRequest.certSigningRequest文件 - 在苹果官方的developer上点击创建证书,上传步骤1中的
CertificateSigningRequest.certSigningRequest文件,然后下载.cer证书文件 - 把这个
.cer先安装到生成CertificateSigningRequest.certSigningRequest的机器上,然后通过导出证书生成带有密码的p12证书文件 - 安装证书,把
p12文件放置到打包服务上,然后点击证书,输入密码,安装到钥匙串的**「"登陆"」** - 如果看到"证书不受信任"的提示,可能是因为缺少AppleWWDRCA证书,可以通过开发者网站安装解决
提示:使用appuploader这类iOS开发助手工具可以简化证书管理流程,它提供了可视化的证书和描述文件管理界面,减少了手动操作的复杂性。
三、配置描述文件
配置完证书后就是配置描述文件,在苹果开发者网站的Profiles创建对应的mobile provision。
- 选择
Distribution-App Store创建对应的打包模式,如果是QA的话一般选择Ad Hoc - 选择需要支持的App Id,也就是bundle Id
- 选择前面生成的
Distribution证书 - 最后输入Provisioning Profile Name,如果是
Ad Hoc可以选择已添加的Devices的UDID - 完成配置后下载
mobile provision文件,将它放到打包机器上的/Users/你的账号/Library/MobileDevice/Provisioning Profiles目录下
如果是store版本的就选择
Distribution-App Store,如果是QA版本的就选择Distribution-Ad Hoc。
四、配置项目
完成了证书和描述文件的配置后,接下来就是针对项目的配置。
首先将需要打包的项目clone到打包机器上(只是为了做测试配置),然后打开项目ios/Runner.xcworkspace目录。
取消选购Automatically manage signing,然后选中我们前面放置的描述文件,就可以看到Xcode会自动匹配到钥匙串里的证书。
通过git diff >./release.patch命令导出一个patch文件,这样在项目被clone下来后,通过git apply直接调整项目的描述文件。
⚠️注意:「第三方打包机器上每次打包都是
clone一个新项目,打包后删除该项目」。
五、开始打包
- 执行
security unlock-keychain -p xxxxx解锁keychain - 通过
flutter build ios --release打包出release模式的App.framework和Flutter.framework - 通过
xcodebuild命令开始编译iOS代码
xcodebuild -workspace Runner.xcworkspace -scheme Runner -sdk iphoneos -configuration Release archive -archivePath $PWD/build/Runner.xcarchive
-
执行完
Archive之后,就可以进入export阶段,exportArchive之前需要先准备一个ExportOptions.plist文件 -
通过指定命令
exportArchive,最终输出ipa文件
xcodebuild -exportArchive -exportOptionsPlist ExportOptions.plist -archivePath $PWD/build/Runner.xcarchive -exportPath $package_path -allowProvisioningUpdates
最后如果是store模式的,可以通过Transporter将ipa上传到App Store Connect,或者使用命令行工具上传。
六、多Flutter版本环境
如果需求有存在多个项目需要在一个机器打包,但是不同项目的Flutter等版本都不同,那么**「对于Mac可以开启多个不同的登陆用户,这样就可以得到不同的打包环境」**。
可以通过安装rvm来管理独立的CocoaPod版本:
- 先通过curl安装rvm
- 通过
rvm install 2.5.5安装对应的ruby版本 - 可以安装多个ruby版本,然后通过
rvm use <Version> --default来使用具体版本 - 在当前ruby版本下安装想要的cocoapods版本
七、最后
通过整个配置过程,可以帮助你了解到iOS打包和认证的详细流程。
在打包Android或iOS时,可以通过--dart-define来指定不同的dart参数:
flutter build ios --release --dart-define=CHANNEL=GSY --dart-define=LANGUAGE=Dart
在dart代码里可以通过String.fromEnvironment获取到对应的自定义配置参数:
const CHANNEL = String.fromEnvironment('CHANNEL');
const LANGUAGE = String.fromEnvironment('LANGUAGE');
小技巧:使用appuploader可以更高效地管理iOS证书和描述文件,它提供了批量操作和自动化功能,特别适合需要频繁打包的团队使用。