iOS模塊化灰度改造
服務能力
To 技術:
新功能模塊級別的 灰度發布.
線上版本回退老版本的能力.
一個App內 打入不同版本模塊的能力.
模塊組裝到不同App的能力. 比如司機端模塊 可以單獨組裝為司機端App 也可與騎手端組裝在一起 打包成司機 + 騎手端App.
支持多個版本并行開發.
To 業務方:
- 不同地區 運行不同版本的業務代碼.
某些地區先試點,時機成熟后 線上動態擴大/縮小試點范圍.
不同地區 不同市場策略 業務邏輯的實現.
新舊版本A/B Test.
預埋節假日模塊,指定節假日不用發版 即可運行節假日模式.
方案概述
第一階段:
將業務代碼拆分到Pods中,不同版本的業務代碼打包成不同的Pods.
由于Swift中不同Pods中的代碼屬于不同的Module,所以將不同的Pods組裝到同一個App內不需要考慮重名的問題.
這樣改造后的App = 穩定版業務代碼Pods + 新開發版本業務代碼Pods + 共用的三方庫代碼.
接入服務端配置中心后,可以在服務端控制Native用戶使用的業務版本.
第二階段:
將第一階段業務代碼拆分為不同的組件,僅對需要灰度的模塊進行多版本的預埋.
客戶端的主動降級保護,啟動App后如果在一定時間內Crash,下次啟動自動降級為穩定版本.
手動配置腳本化.
方案總攬

方案缺點
包內預埋多個版本的模塊 包大小增加.
部分步驟目前需要手工配置xcode.
實施過程
Step 1 將代碼封裝到Pods中管理,制作Podspec.

Step 2 .a形式的靜態庫處理.
由于Pods中無法引入.a形式的靜態庫,需要把.a形式的靜態庫(比如微信支付)封裝為.framework形式的動態庫或者靜態庫.
這里我們封裝為.framework形式的動態庫.
編譯時如果遇到找不到頭文件,請檢查WXPay.framework中的module.modulemap 是否包含下圖中的頭文件.

或者 在 module.modulemap中指定的umbrella header文件WXPay.h中 引入需要暴漏的頭文件 如下圖. 也比較推薦這種方式.

Step 3 部分vendor framework完善.
比如AMap3DMap.framework AMapFoundation.framework中沒有包含module.modulemap的三方framework,
編譯時找不到頭文件,需要手工/腳本添加 module.modulemap.
我們這里可采用在 podfile中添加腳本的方式 具體見下圖:

Step 4 去除之前App工程Header Bridge頭文件.
由于之前Swfit工程通過Header Bridge頭文件去找引入OC代碼的頭文件.改造后引入的庫封裝到Pods中 以framework的形式引入工程,
在添加module.modulemap后無需通過header bridge頭文件的方式引入頭文件.
所以可以在主工程刪除Header Bridge頭文件.
Step 5 header search path 添加vender framework path
在 Build Settings > framework search path 中添加 vender framework的路徑
Step 6 App內內置兩個版本業務代碼Pods后 xcode需要的設置
當預置兩個版本業務代碼Pods后,會出現Pods安裝不成功.
分析一下 項目結構時 主工程 包含 Pods A & Pods B.
Pods A & Pods B包含了同樣的Vendor Framework.
此時我們可以把Pods B中Vendor Framework中的庫刪掉.
然后在Pods B的Target > Build Settings > Framework Search Paths中指向Pods A的Vendor Framework.
達到 主工程 包含 Pods A & Pods B. Pods A & Pods B沒有引入兩份相同的Vendor Framework,而是共用一份Vendor Framework.