來自: 百度搜尋研發部 http://stblog.baidu-tech.com/?p=1295摘要
隨著蘋果手持功能使用者的不斷增加,ios應用也增長迅速,同時隨著iphone被越獄越來越多的app 的渠道也不斷增多,為各個渠道打包成了一件費時費力的工作,本文提供一種比較智能的打包方式來減少其帶來的各種不便。
TAG
Ios打包,app打包,iphone打包,iphone自動化打包,ios打渠道包,iphone自動化打渠道包
自動化打包背景介紹1、背景
隨著ios程式發布的渠道逐漸的增多,為每個渠道打包也成為特別耗費時間和體力的一項技術活了,而這一般大多數都是由rd來完成的。這樣就佔用了rd很多的開發時間,何不把這些東西寫成一個自動化的指令碼,然後交給qa 或是 pm來完成這個打包過程了。經過一番調研發現網上這種指令碼還是很少的,不過xcode 提供了shell編譯工具 xcodebuild 和 ipa打包工具xcrun ,這就有理由讓我們利用這兩個工具寫一個自動化的打包指令碼來提高我們的工作效率和自動化程度。
2、ios程式包格式、渠道包格式
1) 產生多渠道的原因及多渠道帶來的打包問題:隨著iphone、ipad、itouch等手持功能火熱銷售,而它們上面的應用也隨之火爆了起來,而隨之而來的就是以上裝置被越獄後就可以在越獄的裝置上直接運行ipa程式包 而不用通過appstore去下載,這樣一來國內就產生了眾多的專門為越獄手機而開設的渠道提供ipa程式包的下載。隨著越來越多的渠道,推廣時為各個渠道打包就成了一項比較耗費時間和精力的技術活了,因此我們必須尋找一種自動化的方式 讓打包變得高效簡單。
2)Ios程式包分為appstore二進位檔案跟渠道包兩種格式
appstore二進位檔案:通過xcode工具可以產生一個.app格式的二進位檔案。
渠道包:格式為.ipa格式,在沒有自動化打包工具之前都是利用xcode來產生相應的渠道包,而且每次只能產生一個渠道包,每次打包之前都得手動該渠道ID,帶來的問題就是耗費時間、效率低下、容易出錯、增加風險。
3、傳統的ios打包方式
利用xcode 打包
1)appstore 二進位程式包
開啟你的項目,進入“Edit Project Settings”,進入Configuration頁面,選中Release點擊下面的Duplicate,複製一個新的配置項出來,命名為Distribution。然後進入Build頁面,頂上的Configuration下拉框選中Distribution,下面的Code Signing Identity裡面的Any iPhone OS Device後面對應的值選中你的那個Distribution的認證。然後點擊“Build”–> “Build” 就可以編譯器了
編譯成功後,你就可以在相應的build目錄下看到一個.app的二進位檔案。
2)渠道ipa包
根據以上步驟同樣配置好Distribution 認證 ,然後點擊 “Build”–> “Build and Archive” 就可以編譯器了。接著開啟“Window””Organizer” 左側邊欄中選擇”ARCHIVED APPLICATIONS” 然後再右側列表中選中剛才編譯的程式包 再點擊右側右邊頂部的”Share”按鈕 儲存到磁碟即可。就會產生一個.ipa的檔案 即為渠道包。
注意:以上運行裝置必須選擇“Deveice“
4、傳統的打包帶來的問題
耗費時間、耗費體力、效率低下、只能依賴RD來完成、容易出錯、發布風險比較高、QA迴歸確認比較困難、 不智能化。
自動化打包具體實現1、xcodebuild 介紹:
xcodebuild[-project
][-activetarget][-alltargets][-target]...[-parallelizeTargets][-activeconfiguration][-configuration][-sdk |][=]...[]...
xcodebuild[-version[-sdk |]]
xcodebuild[-showsdks]
xcodebuild[-find ][-sdk |]
xcodebuild[-list]
也可以在終端輸入:xcodebuild –help 或 –h查看具體的選項
顯示xcodebuildversion:xcodebuild –version
顯示當前系統安裝的sdk:xcodebuild –showsdks
顯示目前的目錄下project Information:xcodebuild –list
需要注意的是:執行以上命令時必須把位置定位在ios專案檔的根目錄下 否則會提示找不相關命令的。
2、xcrun 介紹:
此工具主要用於將app檔案打包成ipa格式的程式包。(主要用於已越獄手機)。
具體用法如下:
1 |
/usr/bin/xcrun -sdk iphoneos PackageApplication – v [{TARGET}.app] -o [{TARGET}.ipa] --sign [{Iphone Distribution:xxx}] –embed [{xxx.mobileprovision}] |
其中:-v 對應的是app檔案的絕對相對路徑 –o 對應ipa檔案的路徑跟檔案名稱 –sign
對應的是 發布認證中對應的公司名或是個人名 –embed 對應的是發布認證檔案
注意如果對應的Distribution 配置中已經配置好了相關認證資訊的話 –sign 和 –embed可以忽略
3、具體方案
a)從來源程式一次性打出所有渠道的ipa包 跟appstore的二進位包
為了讓自動化指令碼執行一次把所有的渠道包都打好,所以必須有一個設定檔用來儲存所有的渠道名跟渠道號,而專案檔中也應該有個對應儲存當前渠道號的檔案,每次程式都從這個存放渠道號的檔案中讀取渠道號即可,大概的思路就是利用指令碼迴圈執行打包過程,而每次打包前都通過指令碼修改項目中存放渠道號的檔案為當前迴圈的最新渠道號,讓後逐個打包。
註:具體案例見附錄
b)提供一個ipa格式的母包 從母包產生其它所有的渠道包跟 appstore 包
qa的一些疑問,如何確保所有的渠道包就是他們驗證過的那份代碼呢?
的確,以上代碼每次都是重新對程式進行打包,可qa往往測實驗證的只有一個包,如果個個去驗證無意中之中又增加了qa的工作量哈!!而且風險也不可控。因此基於上面的問題我們想出了一下辦法:qa只驗證一個程式包(即母包)如果這個包通過驗證 我們就通過母包去產生其它渠道的包,這樣一來qa也不用確認那麼多的渠道包了,風險也得到了有效控制。
可能你會問:用一個包產生其他的包可行嗎??
原因是這樣的:因為每個渠道只是渠道號發生變化,而其他的內容又不會發生變化,而我們的渠道號又是儲存在sourceid.dat這個檔案中的,所以只要改變母包中的sourceid.dat檔案的內容即可,而ipa包又是同zip格式進行壓縮,所以基本思路就是通過zip先對母包進行解壓,然後改變sourceid.dat的內容 最後再用zip進行壓縮成相應的渠道包即可。
Ipa包的目錄:
註:具體案例見附錄
一些問題
當有些shell命令在mac的終端中運行不通過時,請確保你的shell指令碼是在mac環境下編寫的而不是同xp等其他環境中copy過來的。因為mac跟xp的編碼是不一樣所以會有問題。
總結:
通過從母包打出其他渠道的包這種方法:得到以下好處
i. 降低了rd的工作量,一起qa的工作量。
ii. 讓測試發布程式時的風險得到了控制。
iii. 提高了打包發布工作效率。(幾十個包 只需短短的幾分鐘)。
iv. 提高了自動化。
v. 不依賴mac 以及xcode環境 直接在linux 下即可完成 從母包產生其它包
附錄利用xcode環境一次產生所有包的shell 指令碼代碼:
#!/bin/sh
xcodebuild clean -configuration Distribution //clean項目
distDir="/Users/xxxx/dist"
releaseDir="build/Distribution-iphoneos"
version="1_0_0"
rm -rdf "$distDir"
mkdir "$distDir"
for line in $(cat data.dat) //讀取所有渠道號data.dat檔案
do
ipafilename=`echo $line|cut -f1 -d':'` //渠道名
sourceid=`echo $line|cut -f2 -d':'` //渠道號
echo "ipafilename=$ipaname"
echo "sourceid=$sourceid"
targetName="youtargename" //項目名稱(xcode左邊列表中顯示的項目名稱)
echo "sourceid=$sourceid"
echo "ipafilename=$ipafilename"
echo "$sourceid" > sourceid.dat
echo "sourceid.dat: "
cat sourceid.dat
rm -rdf "$releaseDir"
ipapath="${distDir}/${targetName}_${version}_from_${sourceid}.ipa"
echo "***開始build app檔案***"
xcodebuild -target "$targetName" -configuration Distribution -sdk iphoneos build
appfile="${releaseDir}/${targetName}.app"
if [ $sourceid == "appstore" ]
then
cd $releaseDir
zip -r "${targetName}_${ipafilename}_${version}.zip" "${targetName}.app"
mv "${targetName}_${ipafilename}.zip" $distDir 2> /dev/null
cd ../..
else
echo "***開始打ipa渠道包****"
/usr/bin/xcrun -sdk iphoneos PackageApplication -v "$appfile" -o "$ipapath" --sign "iPhone Distribution:xxxxxx"
fi
done
註:以上的data.dat檔案為存放渠道號列表的檔案 其格式為:3g:1001b 即 (渠道名:渠道號) sourceid.dat 為專案檔中存放渠道號的檔案(內容只有一個渠道號)。當然了上面指令碼只是說明了下如何利用xcodebuild 和 xcrun 進行打包 以及自動打包的一個邏輯,shell指令碼好的同學可以自由發揮哈。。。
從ipa格式的母包產生其它渠道包的shell指令碼執行個體:
#!/bin/sh
sourceipaname="母包名.ipa"
appname=”app檔案名稱.app” //加壓後Pauload目錄項.app檔案名稱需要根據自己的項目修改
distDir="/Users/lxxx/Qa" //打包後檔案儲存體目錄
version="1.0.0"
rm -rdf "$distDir "
mkdir "$distDir" unzip $sourceipaname //解壓母包檔案
for line in $(cat data.dat) //讀取渠道號檔案並進行迴圈
do
ipafilename=`echo $line|cut -f1 -d':'`
sourceid=`echo $line|cut -f2 -d':'`
echo "ipafilename=$ipaname"
echo "sourceid=$sourceid"
targetName="ipa包名"
echo "sourceid=$sourceid"
echo "ipafilename=$ipafilename"
cd Payload
cd $appname
echo "replace sourceid.dat before: "
cat sourceid.dat
echo "$sourceid" > sourceid.dat
echo "replace sourceid.dat after: "
cat sourceid.dat
if [ $sourceid == "appstroe" ]
then
cd ..
zip -r "${targetName}_${version}_from_${sourceid}.zip" $appname //appstore二進位檔案
mv "${targetName}_${version}_from_${sourceid}.zip" $distDir
cd ..
else
cd ../..
zip -r "${targetName}_${version}_from_${sourceid}.ipa" Payload //打成其他渠道的包
mv "${targetName}_${version}_from_${sourceid}.ipa" $distDir
fi
done rm -rdf Payload
註:以上data.dat也是用來儲存所有渠道號的,sourceipaname就是通過qa驗證的母包,appname為ipa包加壓後Payload 目錄下的app檔案名稱並且以上所有檔案必須與指令檔保持在同一目錄下以及在mac環境中執行。