shell技巧5 - 全自動打包ipa
1、前言
最近在研究上傳ipa檔案自動上傳到蘋果後臺(後續有時間也分享給大家啊),然後,就需要製作大量的ipa檔案啊!如果手工的 Archive
那不就死啦,整個步驟,大概要5分針過程,而且不是一步到位等5分鐘,所以就研究了一下專案如何自動打ipa,最後找到了 iOS專案之自動化打包 - 簡書 這篇檔案,然後根據需求,擴充套件做了全能自動化的,app-store、ad-hoc、dev 三種類型證書,另外專案如果是用cocoapod,需要用 -workspace
,否則用 -project
,都做了相當自能化的改造,下面就來看看吧!
2、使用說明
本文,也不打算講 xcodebuild
命令的原理,大家需要自動搜尋,網上很多教程了。所以,我們先過一下,怎麼打包吧!
-
把
build_ipa_shell
指令碼和證書配置資料夾複製到專案 -
根據要求修改專案名字和配置
-
在終端執行
sh build_ipa.sh
,不要求切換到專案的目錄啊,然後選擇打包的型別,然後等待就好!~ > sh /Users/HTC/Desktop/BuildIPAExample/build_ipa_shell/build_ipa.sh Place enter the number you want to export ? [ 1:app-store 2:ad-hoc 3:dev]
-
編譯打包成功後,會自動開啟ipa檔案的目錄!
3、配置說明
上面已經說了 build_ipa.sh
的配置,就是 ExportOptions-appstore.plist
/ ExportOptions-dev.plist
/ ExportOptions-adhoc.plist
三個證書的配置沒有說,其實也很簡單,自己配置,或者讓Xcode生成配置!
自己配置的就不說了,自己搜尋一下教程就好,讓Xcode生成,就是要 Archive
專案,然後選擇 Export...
:
上面三個檔案,就對應下面的三個選項:

如果選擇手動,就是使用本地的證書(如果是選擇自動,就是Xcode中登陸了開發者賬號,自動生成和匹配證書):

等待Xcode生成ipa包,選擇 Export
,Xcode就會自動生成ipa檔案和證書配置檔案,跟我們的指令碼一樣的:

最後,匯出的檔案中,更改 ExportOptions.plist
檔名字為對應的 ExportOptions-appstore.plist
/ ExportOptions-dev.plist
/ ExportOptions-adhoc.plist
,然後複製到 build_ipa_shell
指令碼目錄就可以啦!

4、一些坑點
打包時,遇到下面報錯:
2018-09-17 10:35:23.068 xcodebuild[11322:5883826] [MT] IDEDistribution: Step failed: <IDEDistributionPackagingStep: 0x7ff88e7ab7c0>: Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value., NSFilePath=/var/folders/12/yqg0r8s508lfmzw6b91nh97m0000gn/T/ipatool-json-filepath-vo804k} error: exportArchive: The data couldn’t be read because it isn’t in the correct format. Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value., NSFilePath=/var/folders/12/yqg0r8s508lfmzw6b91nh97m0000gn/T/ipatool-json-filepath-vo804k} ** EXPORT FAILED **
解決方法:
將對應打包的證書plist檔案的 compileBitcode
內容由 true
改為 false
就可以:
<key>compileBitcode</key> <false/>
5、原始碼
具體的程式碼,也可參考我的Github程式碼:
- Shell" target="_blank" rel="nofollow,noindex">iHTCboy/iShell: Shell指令碼程式設計技巧,總結一些常用的提高效率的方法。
#獲取指令碼執行目錄 scrip_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #工程絕對路徑 project_path=$(dirname "$scrip_path") #工程名 將XXX替換成自己的工程名 project_name=BuildIPAExample #scheme名 將XXX替換成自己的sheme名 scheme_name=BuildIPAExample #project_type 專案如果是用cocoapod,就改為 xcworkspace,否則用 xcodeproj project_type=xcodeproj #打包模式 Debug/Release development_mode=Debug #build資料夾路徑 build_path=${project_path}/build #plist檔案所在路徑 exportOptionsPlistPath=${project_path}/build_ipa_shell/ExportOptions-dev.plist echo "Place enter the number you want to export ? [ 1:app-store 2:ad-hoc 3:dev] " read number while([[ $number != 1 ]] && [[ $number != 2 ]] && [[ $number != 3 ]]) do echo "Error! Should enter 1 or 2 or 3" echo "Place enter the number you want to export ? [ 1:app-store 2:ad-hoc 3:dev] " read number done if [ $number == 1 ];then development_mode=Release exportOptionsPlistPath=${project_path}/build_ipa_shell/ExportOptions-appstore.plist elif [ $number == 2 ];then development_mode=Release exportOptionsPlistPath=${project_path}/build_ipa_shell/ExportOptions-adhoc.plist else development_mode=Debug exportOptionsPlistPath=${project_path}/build_ipa_shell/ExportOptions-dev.plist fi #匯出.ipa檔案所在路徑 exportIpaPath=${project_path}/ipa_files/${development_mode} # 生成儲存ipa檔案的目錄 if [ ! -d ${project_path}/ipa_files ]; then mkdir -p ${project_path}/ipa_files; fi # 打包型別 if [ $project_type == "xcodeproj" ]; then project_build=project else project_build=workspace fi # 進入專案目錄,方便後面的操作 cd ${project_path} echo '///-----------' echo '/// 正在清理工程' echo '///-----------' xcodebuild \ clean -configuration ${development_mode} -quiet|| exit echo '///--------' echo '/// 清理完成' echo '///--------' echo '' echo '///-----------' echo '/// 正在編譯工程:'${development_mode} echo '///-----------' xcodebuild \ archive -${project_build} ${project_path}/${project_name}.${project_type} \ -scheme ${scheme_name} \ -configuration ${development_mode} \ -archivePath ${build_path}/${project_name}.xcarchive-quiet|| exit echo '///--------' echo '/// 編譯完成' echo '///--------' echo '' echo '///----------' echo '/// 開始ipa打包' echo '///----------' xcodebuild -exportArchive -archivePath ${build_path}/${project_name}.xcarchive \ -configuration ${development_mode} \ -exportPath ${exportIpaPath} \ -exportOptionsPlist ${exportOptionsPlistPath} \ -quiet || exit if [ -e $exportIpaPath/$scheme_name.ipa ]; then echo '///----------' echo '/// ipa包已匯出' echo '///----------' open $exportIpaPath else echo '///-------------' echo '/// ipa包匯出失敗 ' echo '///-------------' fi echo '///------------' echo '/// 打包ipa完成' echo '///-----------=' echo '' # 開啟生成ipa的目錄 open ${exportIpaPath} # echo '///-------------' # echo '/// 開始釋出ipa包 ' # echo '///-------------' # if [ $number == 1 ];then # #驗證並上傳到App Store # # 將-u 後面的XXX替換成自己的AppleID的賬號,-p後面的XXX替換成自己的密碼 # altoolPath="/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool" # "$altoolPath" --validate-app -f ${exportIpaPath}/${scheme_name}.ipa -u XXX -p XXX -t ios --output-format xml # "$altoolPath" --upload-app -f ${exportIpaPath}/${scheme_name}.ipa -uXXX -p XXX -t ios --output-format xml # else # #上傳到Fir # # 將XXX替換成自己的Fir平臺的token # fir login -T XXX # fir publish $exportIpaPath/$scheme_name.ipa # fi exit 0
6、總結
通過本次指令碼,又讓效率提升了n倍,以後打包不在害怕啦!!!另外,指令碼中,還包含 上傳到 AppStore
或第三方平臺的功能,這裡就先不寫啦,大家有興趣可以自行實踐,和前面幾篇技巧一樣,大家應該能感受到shell指令碼程式設計的魅力,希望大家能舉一反三,授魚不如授漁!生活工作中結合 sehll 指令碼,提高效率和自動化,珍愛時間不是夢!
後續有更多技巧,會繼續給大家分享,期待~
參考
- 如有疑問,歡迎在評論區一起討論!
- 如有不正確的地方,歡迎指導!
注:本文首發於iHTCboy’s blog,如若轉載,請注來源