早幾天客戶發(fā)來信息,說ios 15系統(tǒng)下載蒲公英內(nèi)部分發(fā)安裝失敗了。如下圖


一、糾其病因
第一時間百度、Google、官網(wǎng)都看了看。
參考文章如下:
- http://www.itdecent.cn/p/07cdff01f297
- https://stackoverflow.com/questions/68149213/observing-app-needs-to-be-updated-message-when-launching-app-on-ios-15
- https://developer.apple.com/documentation/xcode/using-the-latest-code-signature-format
根據(jù)官方文檔,iOS在分發(fā)App之前需要對其簽名。當(dāng)是從iOS 15、iPadOS 15、tvOS 15和watchOS 8開始,系統(tǒng)會檢查新的、更安全的簽名格式。而還是使用之前的簽名格式的App將不會啟動。
二、終極解決方案
當(dāng)然了,基于上面的所說的,最好最快速最牛逼的方式當(dāng)然是升級服務(wù)器的系統(tǒng)咯。因?yàn)樵趍acOS 11以上打包就會默認(rèn)使用新的簽名格式,無需擔(dān)心新老簽名的問題。O(∩_∩)O哈哈~
但是有得mac比較老了,升級不上去,不再升級序列,只能全量升級。那就麻煩了,還是用下面的方式簽名吧~
我們就是情況二~
三、首先,需要確定你的App是否需要新的簽名
3.1 有幾種情況是不需要重新簽名處理的
新的簽名方式不會影響大多數(shù)的App,如果你的App是通過App Store或Test Flight分發(fā)的。那么你不需要擔(dān)心,App Store Connect 首先驗(yàn)證您的簽名,然后使用 Apple 身份重新簽名應(yīng)用程序,通過這些渠道提供的應(yīng)用程序已經(jīng)具有新的簽名格式。
如果你的發(fā)布服務(wù)器macOS版本在macOS 11或更高的話,那么也不需要當(dāng)心。因?yàn)樗呀?jīng)默認(rèn)使用新的簽名格式多App進(jìn)行簽名。
3.2 需要進(jìn)行重新簽名的情況
- 發(fā)布服務(wù)器macOS版本比較低,小于11,10.14~11之間的情況就需要重視了,基本上都中招。
3.3 檢測iOS App是否需要重新簽名
- 第一步:需要將ipa包改為zip格式,然后解壓。
- 第二步:解壓后一般會得到一個Payload文件夾,在文件夾里就有一個**.app文件。
- 第三步:對*.app文件使用以下命令
codesign -dv /path/to/MyApp.app

如上圖通過命令,我們可以獲得CodeDirectory v=20400,如果該值小于20400,則表明你需要重新簽名App。
- 第四步:除了第三步,我們最好還需要再用下面這個命令測試以下
codesign -dvvvvv /path/to/MyApp.app


如上兩圖,該命令可以獲得哈希列表,如果-5包含值,而-7沒有或者包含0值的話,則需要重新簽名。簽名完成后,再使用命令得出的會是第二個正確的哈希列表。含有-7,且不為0。
- 第五步:然后用下面的命令重新簽名
Your Codesign Identity:就是你的發(fā)布證書,在鑰匙串里可以找到
codesign -s "Your Codesign Identity" -f --preserve-metadata --generate-entitlement-der /path/to/MyApp.app
簽完之后,重新用“codesign -dvvvvv /path/to/MyApp.app"再次查看哈希列表,確認(rèn)已經(jīng)有-7的值。
- 第六步:壓縮Payload文件,并將其重命名為*.ipa文件(ipa后綴)
至此,重新簽名搞定。
四、將以上步驟寫成腳本
因?yàn)槲覀兛赡苡玫匠掷m(xù)集成,用到了比如說Jenkins之類的,我們就需要把上面的流程寫成腳本
//1. cd到ipa包的目錄下面
project_path="${WORKSPACE}/build/ios/ipa"
cd ${project_path}
//2. 將ipa包重命名為zip包
mv "MyApp.ipa" MyApp.zip
//3. 將zip包進(jìn)行解壓
unzip -q -o MyApp.zip
//4. 解壓之后,并對Payload/*.app文件重新簽名
codesign -s "Your Codesign Identity" -f --preserve-metadata --generate-entitlement-der Payload/MyApp.app
//5. 再將Payload文件夾進(jìn)行壓縮為zip包
zip -q -r -m Payload.zip Payload
//6. 重命名zip包圍*.ipa包
mv Payload.zip MyApp.ipa
//7. 刪除zip包
rm -f MyApp.zip
五、Flutter項目中iOS重新簽名時遇到的問題
如果是原生iOS應(yīng)用,或者用fastline、xcode archive打出的ipa,重簽名,沒問題,妥妥的。
而在我的實(shí)踐中,我們是純Flutter項目,用的Jenkins,flutter build ios命令打包出來的,重新簽名后,哈希值啥的都是有-7,正常的。但是安裝后打開還是出問題了。
安裝打開后,如圖:

5.1 因?yàn)槲覀冎癴lutter命令打包ios的方式如下:
flutter doctor -v
flutter clean
flutter pub get
flutter pub upgrade
flutter pub run build_runner build --delete-conflicting-outputs
flutter build ios --release --flavor dev -t lib/main.dart
if [ -d "build/ios/iphoneos/Runner.app" ]
then
mkdir -p build/app/Payload
cp -r "build/ios/iphoneos/Runner.app" build/app/Payload
cd build/app
zip -r -m MyApp.ipa Payload
cd ..
echo "打包成功"
open app
else
echo "打包失敗"
fi
是使用的flutter build ios命令打包*.app的文件,然后在進(jìn)行壓縮和重命令ipa的。
但是這種方式打出來的ipa,重新簽名后在發(fā)布到蒲公英,下載后安裝打開就會出現(xiàn)上面那種狀況。說“無法安裝此App,無法驗(yàn)證其完整性”。
這讓我百思不得其姐~
5.2 開始一步一步錨定問題
- 首先,我使用xcode的archive打出一個ipa包,對它進(jìn)行重簽名,發(fā)現(xiàn)可以安裝,沒報問題。
- 那我們確定了是flutter build ios這種打包命令有問題
- 然后我去官網(wǎng)找到了另一個命令"flutter build ipa",它可以直接打出一個ipa的包來。 Build and release an iOS app
flutter build ipa --export-options-plist=path/to/ExportOptions.plist
但是它需要提前配置一個ExportOptions.plist的plist文件,這個文件你可以使用你的xcode archive打包導(dǎo)出ipa的時候,它也會生成ExportOptions.plist這樣的文件。你也可以直接使用它。
該文件可以放置工程目錄或者你指定的地方,只要你執(zhí)行腳本時找得到就行。
ExportOptions.plist文件內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>ad-hoc</string>
<key>teamID</key>
<string>發(fā)布證書ID</string>
</dict>
</plist>
使用"flutter build ipa",也配置了ExportOptions.plist文件后,發(fā)現(xiàn)它確實(shí)可以打出xcarchive文件來,但是始終沒有打出ipa包來。
然后試了下,用生成的xcarchive文件,在xcode上簽名,發(fā)現(xiàn)可以導(dǎo)出ipa來,驗(yàn)證了xcarchive文件是沒啥問題的。
然后我去找了用xcodebuild命令將archive打包成ipa
xcodebuild -exportArchive -archivePath /Path/To/Output/YourApp.xcarchive -exportPath /Path/To/ipa/Output/Folder -exportOptionsPlist /Path/To/ExportOptions.plist
發(fā)現(xiàn)也不成功,老是報錯:

然后,搜了下日志和網(wǎng)頁發(fā)現(xiàn)是sqlite3沒有安裝的問題:xcode 腳本打包報錯 error: exportArchive: The data couldn’t be read because it isn’t in the correct format
安裝了sqlite3之后,重啟電腦,在使用flutter build ipa命令就可以直接打出ipa的包來了
在進(jìn)行重簽名步驟,上傳蒲公英,下載安裝就妥妥滴了~