作為一名客戶端開發(fā)人員,每次給測(cè)試打包都是一件很痛苦的事情,因?yàn)橛袝r(shí)候隨便改點(diǎn)一些小Bug,測(cè)試要回歸測(cè)試,一天之內(nèi)可能會(huì)不斷的打包n個(gè)版本,如果讓開發(fā)人員每次都手動(dòng)打包,不僅是浪費(fèi)了開發(fā)者的時(shí)間,同時(shí)也浪費(fèi)了測(cè)試組的時(shí)間。所以此時(shí)自動(dòng)化打包是顯得多么的重要,節(jié)省了開發(fā)者和測(cè)試組的大量時(shí)間。有了自動(dòng)化打包工具,開發(fā)人員只需要將修改的代碼提交到遠(yuǎn)程倉(cāng)庫(kù)即可,剩下的事就交給自動(dòng)化打包工具吧。在一切都OK后需要打包上傳到iTunes Connect上,此時(shí)只需要修改一個(gè).plist配置文件就可以。給測(cè)試組的寶寶們教一下如何把ipa文件上傳到iTunes Connect,并發(fā)布,以后這些小事就可以交給他們做了。O(∩_∩)O哈哈哈~

基本命令
主要有以下2種方法:
-
xcrun: 把*.app打包成ipa。 -
xcodebuild: 生成Archive、導(dǎo)出ipa。
由于之前在網(wǎng)上查到資料,對(duì)比了兩者的區(qū)別,有人說(shuō)是第一種命令,
xcrun有點(diǎn)out了,不太適合現(xiàn)在的打包了,本人也沒有去真正測(cè)試是否到底好用,所以在此只介紹第二種命令xcodebuild的使用,這也是我目前正在用的。在我們的項(xiàng)目中有2個(gè)shell腳本,一個(gè)是用來(lái)打包測(cè)試版的,一個(gè)是用來(lái)打發(fā)布到App Store版的,不用的環(huán)境運(yùn)行不同的腳本。
xcodebuild 的基本使用
xcodebuild命令打包主要有2個(gè)步驟,搞清楚這兩個(gè)步驟,其他的就是個(gè)性化的東西了(比如:打包前修改一些配置文件,生成的ipa的命名等都可以放在腳本里去做)。
第一步:編譯打包成Archive 就如在Xcode操作「Product -> Archive」
xcodebuild archive -workspace XXX.xcworkspace -scheme XXX -configuration Release -archivePath ${ARCHIVE_PATH} CONFIGURATION_BUILD_DIR=${CONFIGURATION_BUILD_PATH}
參數(shù)說(shuō)明:
-workspace:指定工作空間文件XXX.xcworkspace
-scheme:指定構(gòu)建工程名稱
-configuration:[Debug/Release]可選項(xiàng),選擇Debug或者Release構(gòu)建
-archivePath:保存生成.xcarchive包路徑
CONFIGURATION_BUILD_DIR:build時(shí)的文件路徑(主要包含.a文件、XXX.app文件和XXX.app.dSYM文件)如果不需要用到XXX.app.dSYM文件中的二進(jìn)制文件(有些第三方崩潰統(tǒng)計(jì)需要用到此文件),可以不加此項(xiàng)。
第二步:用生成的XXX.xcarchive文件導(dǎo)出為XXX.ipa文件
xcodebuild -exportArchive -archivePath ${ARCHIVE_PATH} -exportOptionsPlist ${EXPORT_OPTIONS_PLIST_PATH} -exportPath ${EXPORT_DIR}
參數(shù)說(shuō)明:
-archivePath:第一步中生成XXX.xcarchive文件的路徑
-exportOptionsPlist:導(dǎo)出過(guò)程中需要的配置文件路徑(我是放在工程文件夾中的)
-exportPath:導(dǎo)出ipa保存目錄
exportOptionsPlist文件參數(shù)如下圖:


以上兩步是最核心的兩步,理解了各個(gè)參數(shù)的用意,就明白是怎么回事了。xcodebuild還有其他用法,可以通過(guò)命令xcodebuild -usage查看相關(guān)說(shuō)明。
具體使用
下面是我用的打包腳本,是用于打包發(fā)布到App Store版的,需要用到打包測(cè)試版的話,自己動(dòng)手修改一下,也當(dāng)做學(xué)習(xí)了。其中很多用到了變量名,可能看起來(lái)會(huì)有點(diǎn)費(fèi)勁,自己看的時(shí)候捋一捋吧。
# !/bin/bash
# 時(shí)間字符串格式化輸出 eg:2016-11-14 22:40
# date_value=` date "+%Y-%m-%d %H:%M"`
# 執(zhí)行 ./build-redlips_appStore.sh release 打包
PROJECT="XXX"
WORKSPACE_FILE=${PROJECT}.xcworkspace
TARGET="XXX"
BUILD_CONFIGURATION="Debug"
if [ "$1" = "release" ]; then
BUILD_CONFIGURATION="Release"
fi
#新建3個(gè)文件夾路徑(我是都放在桌面),用來(lái)保存打包時(shí)相關(guān)的文件
CONFIGURATION_BUILD_DIR=~/Desktop/build_configuration
ARCHIVE_DIR=~/Desktop/build_archive
EXPORT_DIR=~/Desktop/build_ipa
# LOG_PATH=~/Desktop/build_log
# LOG_PATH是一個(gè)文檔路徑,只是用來(lái)記錄命令的輸出,因?yàn)槎即蛟诮K端會(huì)很多,另外也方便后面分析。后面的命令也是如此。這里面帶的選項(xiàng)可以根據(jù)需要參考xcodebuild -help的信息。
# clean
# 清理構(gòu)建目錄 就如在Xcode操作「Product -> Clean」。
xcodebuild clean -configuration ${BUILD_CONFIGURATION} -alltargets
# 移除之前的目錄并創(chuàng)建新的文件夾(可以不執(zhí)行此操作)
rm -rf ${CONFIGURATION_BUILD_DIR}
rm -rf ${ARCHIVE_DIR}
rm -rf ${EXPORT_DIR}
mkdir ${CONFIGURATION_BUILD_DIR}
mkdir ${ARCHIVE_DIR}
mkdir ${EXPORT_DIR}
# 編譯打包成Archive 就如在Xcode操作「Product -> Archive」
CONFIGURATION_BUILD_PATH=${CONFIGURATION_BUILD_DIR}/${BUILD_CONFIGURATION}-iphoneos
# archivePath="~/Desktop/build_archive/${TARGET}.xcarchive"
ARCHIVE_PATH=${ARCHIVE_DIR}/${TARGET}.xcarchive
# CODE_SIGN_IDENTITY="$codeSignIdentity" PROVISIONING_PROFILE="$provisioningProfile"
xcodebuild archive -workspace ${WORKSPACE_FILE} -scheme ${TARGET} -configuration ${BUILD_CONFIGURATION} -archivePath ${ARCHIVE_PATH} CONFIGURATION_BUILD_DIR=${CONFIGURATION_BUILD_PATH}
# 將Archive導(dǎo)出 (注意路徑加""號(hào)和不加""的寫法)
# exportOptionsPlist="/Users/apple/Desktop/XXX/XXX/Src/Common/AppStoreExportOptions.plist"
# 取出當(dāng)前目錄的路徑進(jìn)行拼接(每人的項(xiàng)目文件名可能不一樣)
BASE_PATH=${PWD}
EXPORT_OPTIONS_PLIST_PATH=${BASE_PATH}/XXX/Src/Common/AppStoreExportOptions.plist
xcodebuild -exportArchive -archivePath ${ARCHIVE_PATH} -exportOptionsPlist ${EXPORT_OPTIONS_PLIST_PATH} -exportPath ${EXPORT_DIR}
****************************** 分割線 ******************************
#下面是獲取上傳到第三方統(tǒng)計(jì)崩潰日志的文件,如果沒有用到可以到此結(jié)束
# 復(fù)制(or壓縮) CONFIGURATION_BUILD_PATH 目錄下的 XXX.app.dSYM 文件(其實(shí)是個(gè)文件夾)到 EXPORT_DIR 目錄下
DSYM_PATH=${CONFIGURATION_BUILD_PATH}/${TARGET}.app.dSYM
DSYM_ZIP_PATH=${EXPORT_DIR}/${TARGET}.app.dSYM.zip
DSYM_COPY_PATH=${EXPORT_DIR}
# zip -r 目標(biāo)路徑 源文件路徑
zip -r ${DSYM_ZIP_PATH} ${DSYM_PATH}
# cp -r 源文件路徑 目標(biāo)路徑
cp -r ${DSYM_PATH} ${DSYM_COPY_PATH}
# 復(fù)制 XXX.app.dSYM 包里的 XXX 文件 上傳到聽云
TARGET_PATH=${DSYM_COPY_PATH}/${TARGET}.app.dSYM/Contents/Resources/DWARF/${TARGET}
cp ${TARGET_PATH} ${EXPORT_DIR}
溫馨提醒
- 打包前記得把你的證書和簽名設(shè)置正確,否則打包必定失敗。
- 如果添加了iOS10的通知特性(PushNotificationService),記得在工程中TARGETS下選擇PushNotificationService,Build Settings欄目下,Enable Bitcode屬性設(shè)置為NO。否則打包成功在上傳到iTunes Connect時(shí),會(huì)出現(xiàn)如下錯(cuò)誤:
ERROR ITMS-90635: "Invalid Mach-O Format. The Mach-O in bundle "XXX.app/PlugIns/XXXPushNotificationService.appex" isn’t consistent with the Mach-O in the main bundle. The main bundle Mach-O contains armv7(machine code) and arm64(machine code), while the nested bundle Mach-O contains armv7(bitcode) and arm64(bitcode). Verify that all of the targets for a platform have a consistent value for the ENABLE_BITCODE build setting."
以上就是我打包用到的腳本,至于打包測(cè)試版的,我就不展示了,伙伴們可以自己動(dòng)手寫一個(gè),就當(dāng)練習(xí)了,畢竟自己動(dòng)手豐衣足食嘛,哈哈....