技 術(shù) 文 章 / 超 人
自動(dòng)化打包方案1:xcodebuild打包
使用xcodebuild自動(dòng)化打包給我的感覺就是用命令行來控制Xcode進(jìn)行編譯打包,xcodebuild打包有3種,一種是adHoc測(cè)試打包ipa,一個(gè)是上傳AppStore打包,一個(gè)企業(yè)級(jí)別打包。具體區(qū)別請(qǐng)看下面的步驟中說明
了解xcodebuild打包先從終端操作開始,廢話不多說,擼起袖子干。
步驟1:
首先打開終端 cd到當(dāng)前工程目錄步驟2:
在終端中輸入一下內(nèi)容來完成編譯
xcodebuild archive -workspace XXX.xcworkspace -scheme XXX -configuration Release -archivePath ./myArchivePath CONFIGURATION_BUILD_DIR ./dir ODE_SIGN_IDENTITY=證書 PROVISIONING_PROFILE=描述文件UUID
| key | 說明 |
|---|---|
| -workspace XXX.xcworkspace | XXX.xcworkspace需要編譯工程的工作空間名稱,如果工程不是.xcworkspace的,可以不需要-workspace XXX.xcworkspace這段話 |
| -scheme XXX | XXX是工程名稱,-scheme XXX是指定構(gòu)建工程的名稱 |
| -configuration Release | 填入打包的方式是Debug或Release,就跟在Xcode中編譯前需要在Edit scheme的Build configuration中選擇打出來的包是Debug還是Release包一樣,-configuration就是配置編譯的Build configuration |
| -archivePath ./myArchivePath | 配置生成.xcarchive的路徑, ./表示生成在當(dāng)前目錄下,myArchivePath是生成的.Archive文件名稱 |
| ODE_SIGN_IDENTITY=證書 | 配置打包的指定證書,如果該工程的Xcode已經(jīng)配置好了證書,那么不加入這段話也可以,打包出來的證書就是Xcode中配置好的。 |
| PROVISIONING_PROFILE=描述文件UUID | 配置打包的描述文件,同上,Xcode已經(jīng)配置好了就不用在填入這段話了 |
| CONFIGURATION_BUILD_DIR | 配置編譯文件的輸出路徑,如果需要用到.xcarchive文件內(nèi)部的dSYM等文件,可以使用改字段指定輸出路徑。 |
如果工程是勾選了Automatically manage signing,那么就不用在配置ODE_SIGN_IDENTITY和PROVISIONING_PROFILE

獲取證書名:

獲取描述文件UUID:
首先在Finder中前往/Users/用戶名/Library/MobileDevice/Provisioning Profiles路徑

然后在Provisioning Profiles文件夾中選擇打包需要的描述文件,一般描述文件的文件名都是由UUID組成的,如果文件名不是由UUID組成的,可以在終端中cd到Provisioning Profiles路徑,輸入
/usr/bin/security cms -D -i 23ec4472-bfc4-4128-a96c-2018021f52f3.mobileprovision,23ec4472-bfc4-4128-a96c-2018021f52f3.mobileprovision是描述文件的名稱,然后在終端的解析結(jié)果中找到UUID

輸入步驟2的命令后,終端會(huì)輸出十多秒,在你指定的路徑下生成.xcarchive文件

右鍵點(diǎn)擊.xcarchive文件的顯示包內(nèi)容,其中包含dSYM和app

-
步驟3:配置打包的ExportOptions.plist文件
可以在任意一個(gè)Xcode工程中新建一個(gè)ExportOptions.plist文件。adHoc和AppStore的配置文件內(nèi)容不一樣
image.png
adHoc的配置內(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>compileBitcode</key>//是否編譯bitcode
<true/>
<key>method</key>
<string>ad-hoc</string>/
<key>provisioningProfiles</key>
<dict>
<key>文件bundle id</key>
<string>Adhoc_ID</string>
</dict>
<key>signingCertificate</key>//證書簽名
<string>這里填證書簽名</string>
<key>signingStyle</key>
<string>manual</string>
<key>stripSwiftSymbols</key>
<true/>
<key>teamID</key>
<string>AANCCUK4M3</string>//TeamID
<key>thinning</key>
<string><none></string>
</dict>
</plist>

App Store配置內(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>app-store</string>
<key>provisioningProfiles</key>
<dict>
<key>這里填應(yīng)用的bundle id</key>
<string>這里填對(duì)應(yīng)budle id的證書名</string>
</dict>
<key>signingCertificate</key>
<string>這里填簽名證書</string>
<key>signingStyle</key>
<string>manual</string>
<key>stripSwiftSymbols</key>
<true/>
<key>teamID</key>
<string>這里是teamID</string>
<key>uploadBitcode</key>
<false/>
<key>uploadSymbols</key>
<false/>
</dict>
</plist>

如果實(shí)在不知道plist文件如何寫,可以自己先手動(dòng)打一個(gè)AdHoc和Appstore的包,生成的文件中就會(huì)有一個(gè)ExportOptions.plist文件,看看里面的區(qū)別,也可以拿過來直接用。
-
步驟4:工程路徑下的終端中輸入
xcodebuild -exportArchive -archivePath ./myArchivePath.xcarchive -exportOptionsPlist ./ExportOptions.plist -exportPath ./out,這一步實(shí)際就是Xcode編譯號(hào)后在工程中勾選打包的選擇。只是用配置文件的方式來抵銷手動(dòng)選擇。
| key | 說明 |
|---|---|
| -archivePath ./myArchivePath.xcarchive | 指定需要打包的.xcarchive路徑,./myArchivePath.xcarchive表示在當(dāng)前終端路徑下的myArchivePath.xcarchive文件 |
| -exportOptionsPlist ./ExportOptions.plist | 指定打包需要的ExportOptions.plist配置文件路徑 |
| -exportPath ./out | 指定打包輸出的路徑, ./out表示打包結(jié)果輸出在終端的當(dāng)前路徑下的out文件家中。如果沒有out文件夾會(huì)自動(dòng)創(chuàng)建一個(gè) |
這樣就完成了終端里的打包。
當(dāng)你明白打包的具體步驟后,我們就可以把上面的步驟放在shell腳本中,然后在終端用一個(gè)命令來執(zhí)行shell腳本來實(shí)現(xiàn)自動(dòng)打包,更加簡便。
制作腳本:
首先:cd到需要自動(dòng)打包的工程下
然后:在終端中輸入touch xcodebuild.sh創(chuàng)建xcodebuild.sh腳本文件
然后:雙擊打開腳本寫入下面 腳本內(nèi)容(請(qǐng)確保所有版本的plist配置文件都寫好了)
最后:在終端中輸入 ./xcodebuild.sh運(yùn)行腳本,按照步驟完成打包選擇(如果運(yùn)行的時(shí)候出現(xiàn)Permission denied,請(qǐng)先在終端中執(zhí)行chmod a+x *.文件的后綴名 后,在運(yùn)行。
)
腳本內(nèi)容
#author by heyujia
#腳本所在的目錄必須和WorkSpace或者說工程主目錄所在的目錄在同一個(gè)目錄層級(jí)中
#配置參數(shù)
#workspace的名字,如果沒有則不需要這段話,我測(cè)試工程不是一個(gè)工作空間所以就沒用,如果需要用的話,還需要在編譯階段的腳本代碼里加上 -workspace ${Project_Name}.xcworkspace
#Workspace_Name="WorkSpace名字"
#工程名字
Project_Name="Demo"
#配置打包方式Release或者Debug
Configuration="Release"
#基礎(chǔ)主路徑
BUILD_PATH=./build
#不同版本的基礎(chǔ)子路徑
#adHoc
ADHOC_PATH=${BUILD_PATH}/adHoc
#appStore
APPSTORE_PATH=${BUILD_PATH}/appStore
#enterprise
ENTERPRISE_PATH=${BUILD_PATH}/enterprise
#配置編譯文件的存放地址
#adHoc
CONFIGURATION_BUILD_PATH_ADHOC=${ADHOC_PATH}/${Configuration}-iphoneos
#appStore
CONFIGURATION_BUILD_PATH_APPSTORE=${APPSTORE_PATH}/${Configuration}-iphoneos
#企業(yè)
CONFIGURATION_BUILD_PATH_ENTERPRISE=${ENTERPRISE_PATH}/${Configuration}-iphoneos
#下面是獲取上傳到第三方統(tǒng)計(jì)崩潰日志的文件,如果沒有用到可以刪除該部分
#adHoc
DSYM_PATH_ADHOC=${CONFIGURATION_BUILD_PATH_ADHOC}/${Project_Name}.app.dSYM
DSYM_ZIP_PATH_ADHOC=${ADHOC_PATH}/${Project_Name}.app.dSYM.zip
DSYM_COPY_PATH_ADHOC=${ADHOC_PATH}/copy
#appStore
DSYM_PATH_APPSTORE=${CONFIGURATION_BUILD_PATH_APPSTORE}/${Project_Name}.app.dSYM
DSYM_ZIP_PATH_APPSTORE=${APPSTORE_PATH}/${Project_Name}.app.dSYM.zip
DSYM_COPY_PATH_APPSTORE=${APPSTORE_PATH}/copy
#企業(yè)
#appStore
DSYM_PATH_ENTERPRISE=${CONFIGURATION_BUILD_PATH_ENTERPRISE}/${Project_Name}.app.dSYM
DSYM_ZIP_PATH_ENTERPRISE=${ENTERPRISE_PATH}/${Project_Name}.app.dSYM.zip
DSYM_COPY_PATH_ENTERPRISE=${ENTERPRISE_PATH}/copy
#配置打包結(jié)果輸出的路徑
#AdHoc版本
AdHocPrijectOutPath=${ADHOC_PATH}/adHocOut
#AppStore版本
AppStorePrijectOutPath=${APPSTORE_PATH}/appStoreOut
#企業(yè)版本
EnterprisePrijectOutPath=${ENTERPRISE_PATH}/enterpriseOut
#如果工程中配置了Automatically manage signing,那么就不需要證書名和描述文件名,請(qǐng)確保工程中配置的證書名和描述文件是你打包想要用的
#ADHOC證書名#描述文件
ADHOCCODE_SIGN_IDENTITY="iPhone Distribution: xxxx"
ADHOCPROVISIONING_PROFILE_NAME="xxxxx-xxxx-xxxx-xxxx-xxxxxx"
#AppStore證書名#描述文件
APPSTORECODE_SIGN_IDENTITY="iPhone Distribution: xxxxx"
APPSTOREROVISIONING_PROFILE_NAME="xxxxx-xxxx-xxxx-xxxx-xxxxxx"
#企業(yè)(enterprise)證書名#描述文件
ENTERPRISECODE_SIGN_IDENTITY="iPhone Distribution: xxxx"
ENTERPRISEROVISIONING_PROFILE_NAME="xxxxx-xxxx-xxx-xxxx"
#加載各個(gè)版本的plist文件,為了實(shí)現(xiàn)一個(gè)腳本打包所有版本,這里對(duì)不同對(duì)版本創(chuàng)建了不同的plist配置文件。等號(hào)后面是文件路徑,一般把plist文件放在與腳本同一級(jí)別的文件層中。我這里測(cè)試用所以plist文件都一樣,實(shí)際使用是請(qǐng)分開配置為不同文件
ADHOCExportOptionsPlist="./ExportOptions.plist"
AppStoreExportOptionsPlist="./ExportOptions.plist"
EnterpriseExportOptionsPlist="./ExportOptions.plist"
#在終端中提示 根據(jù)輸入的序號(hào)不同,打包成不同版本的ipa
echo "~~~~~~~~~~~~選擇打包方式(輸入序號(hào))~~~~~~~~~~~~~~~"
echo " 1 adHoc"
echo " 2 AppStore"
echo " 3 Enterprise"
# 讀取用戶在終端中輸入并存到變量里
read parameter
sleep 0.5
method="$parameter"
# 判讀用戶是否有輸入
if [ -n "$method" ]
then
if [ "$method" = "1" ]
then
#這里都執(zhí)行命令中是在xcworkspace工程中執(zhí)行的,如果工程不是xcworkspace,可以把-workspace的內(nèi)容刪掉,加入了證書和描述文件,如果不需要請(qǐng)刪除
#如果用戶選擇的是1,就執(zhí)行adhoc腳本
#首先清除原來的文件夾
rm -rf ${BUILD_PATH}
#創(chuàng)建文件夾,路徑需要一層一層創(chuàng)建,不然會(huì)創(chuàng)建失敗
mkdir ${BUILD_PATH}
mkdir ${ADHOC_PATH}
#編譯文件
mkdir ${CONFIGURATION_BUILD_PATH_ADHOC}
#打包輸出的文件
mkdir ${AdHocPrijectOutPath}
#copy
mkdir ${DSYM_COPY_PATH_ADHOC}
#編譯
xcodebuild archive -scheme $Project_Name -configuration $Configuration -archivePath ${ADHOC_PATH}/$Project_Name-adhoc.xcarchive CONFIGURATION_BUILD_DIR=${CONFIGURATION_BUILD_PATH_ADHOC}
#如果需要單獨(dú)設(shè)置證書和描述文件需要在編譯時(shí)加入下面這句話
#CODE_SIGN_IDENTITY="${ADHOCCODE_SIGN_IDENTITY}" PROVISIONING_PROFILE="${ADHOCPROVISIONING_PROFILE_NAME}" PRODUCT_BUNDLE_IDENTIFIER="${AdHocBundleID}"
#打包
xcodebuild -exportArchive -archivePath ${ADHOC_PATH}/$Project_Name-adhoc.xcarchive -exportOptionsPlist $ADHOCExportOptionsPlist -exportPath ${AdHocPrijectOutPath}
# 選擇是壓縮還是復(fù)制,復(fù)制的方法可以用于上傳文件到指定服務(wù)器,比如上傳到git
# zip -r 目標(biāo)路徑 源文件路徑 ,開始?jí)嚎sdSYM文件
zip -r ${DSYM_ZIP_PATH_ADHOC} ${DSYM_PATH_ADHOC}
# cp -r 源文件路徑 目標(biāo)路徑 , 把壓縮包拷貝到指定地方
cp -r ${DSYM_ZIP_PATH_ADHOC} ${DSYM_COPY_PATH_ADHOC}
# 復(fù)制 dSYM 包里的 XXX 文件 上傳到指定的地方
#TARGET_PATH=${DSYM_COPY_PATH}/${TARGET}.app.dSYM/Contents/Resources/DWARF/${TARGET}
#cp ${TARGET_PATH} ${EXPORT_DIR}
elif [ "$method" = "2" ]
then
#如果用戶選擇的是2,就執(zhí)行appstore腳本
#首先清除原來的文件夾
rm -rf ${BUILD_PATH}
#創(chuàng)建文件夾,路徑需要一層一層創(chuàng)建,不然會(huì)創(chuàng)建失敗
mkdir ${BUILD_PATH}
mkdir ${APPSTORE_PATH}
#編譯文件
mkdir ${CONFIGURATION_BUILD_PATH_APPSTORE}
#打包輸出的文件
mkdir ${AppStorePrijectOutPath}
#copy
mkdir ${DSYM_COPY_PATH_APPSTORE}
xcodebuild archive -scheme $Project_Name -configuration $Configuration -archivePath ${APPSTORE_PATH}/$Project_Name-appstore.xcarchive CONFIGURATION_BUILD_DIR=${CONFIGURATION_BUILD_PATH_APPSTORE}
xcodebuild -exportArchive -archivePath ${APPSTORE_PATH}/$Project_Name-appstore.xcarchive -exportOptionsPlist $AppStoreExportOptionsPlist -exportPath ${AppStorePrijectOutPath}
#創(chuàng)建copy文件夾
mkdir ${DSYM_COPY_PATH_APPSTORE}
# 選擇是壓縮還是復(fù)制,復(fù)制的方法可以用于上傳文件到指定服務(wù)器,比如上傳到git
# zip -r 目標(biāo)路徑 源文件路徑 ,開始?jí)嚎sdSYM文件
zip -r ${DSYM_ZIP_PATH_APPSTORE} ${DSYM_PATH_APPSTORE}
# cp -r 源文件路徑 目標(biāo)路徑 , 把壓縮包拷貝到指定地方
cp -r ${DSYM_ZIP_PATH_APPSTORE} ${DSYM_COPY_PATH_APPSTORE}
#驗(yàn)證ipa是否打包成功
if [ -e $AppStorePrijectOutPath/$Project_Name.ipa ]; then
echo '----ipa包已生成----'
open $AppStorePrijectOutPath
echo '----打包ipa完成----'
echo '**---------------**'
echo '****開始發(fā)布ipa包****'
echo '**---------------**'
#驗(yàn)證后上傳到App Store
# 將-u 后面的XXX替換成自己的AppleID的賬號(hào),-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 -u XXX -p XXX -t ios --output-format xml
else
echo '----ipa包導(dǎo)出失敗----'
fi
elif [ "$method" = "3" ]
then
#如果用戶選擇的是3,就執(zhí)行企業(yè)腳本
#首先清除原來的文件夾
rm -rf ${BUILD_PATH}
#創(chuàng)建文件夾,路徑需要一層一層創(chuàng)建,不然會(huì)創(chuàng)建失敗
mkdir ${BUILD_PATH}
mkdir ${ENTERPRISE_PATH}
#編譯文件
mkdir ${CONFIGURATION_BUILD_PATH_ENTERPRISE}
#打包輸出的文件
mkdir ${EnterprisePrijectOutPath}
#copy
mkdir ${DSYM_COPY_PATH_ENTERPRISE}
xcodebuild archive -scheme $Project_Name -configuration $Configuration -archivePath ${ENTERPRISE_PATH}/$Project_Name-enterprise.xcarchive CONFIGURATION_BUILD_DIR=${CONFIGURATION_BUILD_PATH_ENTERPRISE}
xcodebuild -exportArchive -archivePath ${ENTERPRISE_PATH}/$Project_Name-enterprise.xcarchive -exportOptionsPlist $EnterpriseExportOptionsPlist -exportPath ${EnterprisePrijectOutPath}
#創(chuàng)建copy文件夾
mkdir ${DSYM_COPY_PATH_ENTERPRISE}
# 選擇是壓縮還是復(fù)制,復(fù)制的方法可以用于上傳文件到指定服務(wù)器,比如上傳到git
# zip -r 目標(biāo)路徑 源文件路徑 ,開始?jí)嚎sdSYM文件
zip -r ${DSYM_ZIP_PATH_ENTERPRISE} ${DSYM_PATH_ENTERPRISE}
# cp -r 源文件路徑 目標(biāo)路徑 , 把壓縮包拷貝到指定地方
cp -r ${DSYM_ZIP_PATH_ENTERPRISE} ${DSYM_COPY_PATH_ENTERPRISE}
# 將 dSYM 包里的 demo 文件 上傳到指定地點(diǎn)
TARGET_PATH=${DSYM_COPY_PATH}/${Project_Name}.app.dSYM/Contents/Resources/DWARF/${Project_Name} cp ${TARGET_PATH} ${EXPORT_DIR}
else
#如果是其他輸入,則在終端中提示參數(shù)無效并退出
echo "參數(shù)無效...."
exit 1
fi
fi
注意:在寫腳本的時(shí)候,要注意=號(hào)的前后不要有空格,我寫OC代碼風(fēng)格都是喜歡 =號(hào) 前后空格,這樣間距美觀。但是腳本里如果有空格會(huì)造成命令無效。
自動(dòng)化打包方案2
...未完待續(xù)
