本篇主要作為前文的補充,介紹一些構建上的調整
在 《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 化的貢獻吧~