本文最終實(shí)現(xiàn)的是使用腳本打 Ad-hoc 包,并發(fā)布測試闷堡,當(dāng)然稍微修改一下腳本參數(shù)就可以打其他類型的 ipa 包了。另外該腳本還實(shí)現(xiàn)了將生成的 ipa 包上傳至蒲公英進(jìn)行測試分發(fā)。
xcodebuild 簡介
xcodebuild是蘋果提供的打包項目或者工程的命令搪锣,了解該命令最好的方式就是使用 man xcodebuild查看其 man page. 盡管是英文丢郊,一定要老老實(shí)實(shí)的讀一遍就好了盔沫。
DESCRIPTION
xcodebuild builds one or more targets contained in an Xcode project, or builds a scheme contained in an Xcode workspace or Xcode project.
Usage
To build an Xcode project, run xcodebuild from the directory containing your project (i.e. the directory containing the name.xcodeproj package). If you have multiple projects in the this directory you will need to use -project to indicate which project should be built. By default, xcodebuild builds the first target listed in the project, with the default build configuration. The order of the targets is a property of the project and is the same for all users of the project.
To build an Xcode workspace, you must pass both the -workspace and -scheme options to define the build. The parameters of the scheme will control which targets are built and how they are built, although you may pass other options to xcodebuild to override some parameters of the scheme.
There are also several options that display info about the installed version of Xcode or about projects or workspaces in the local directory, but which do not initiate an action. These include -list, -showBuildSettings, -showsdks, -usage, and -version.
總結(jié)一下:
需要在包含 name.xcodeproj 的目錄下執(zhí)行 xcodebuild命令,且如果該目錄下有多個 projects枫匾,那么需要使用 -project指定需要 build 的項目架诞。
在不指定 build 的 target 的時候,默認(rèn)情況下會 build project 下的第一個 target
當(dāng) build workspace 時干茉,需要同時指定 -workspace和 -scheme參數(shù)谴忧,scheme 參數(shù)控制了哪些 targets 會被 build 以及以怎樣的方式 build。
有一些諸如 -list, -showBuildSettings, -showsdks
的參數(shù)可以查看項目或者工程的信息角虫,不會對 build action 造成任何影響沾谓,放心使用。
那么戳鹅,xcodebuild
究竟如何使用呢均驶? 繼續(xù)看文檔:
xcodebuild [-project name.xcodeproj] [[-target targetname] … | -alltargets] [-configuration configurationname] [-sdk [sdkfullpath | sdkname]] [action …] [buildsetting=value …] [-userdefault=value …]
xcodebuild [-project name.xcodeproj] -scheme schemename [[-destination destinationspecifier] …] [-destination-timeout value] [-configuration configurationname] [-sdk [sdkfullpath | sdkname]] [action …] [buildsetting=value …] [-userdefault=value …]
xcodebuild -workspace name.xcworkspace -scheme schemename [[-destination destinationspecifier] …] [-destination-timeout value] [-configuration configurationname] [-sdk [sdkfullpath | sdkname]] [action …] [buildsetting=value …] [-userdefault=value …]
xcodebuild -version [-sdk [sdkfullpath | sdkname]] [infoitem]
xcodebuild -showsdks
xcodebuild -showBuildSettings [-project name.xcodeproj | [-workspace name.xcworkspace -scheme schemename]]
xcodebuild -list [-project name.xcodeproj | -workspace name.xcworkspace]
xcodebuild -exportArchive -archivePath xcarchivepath -exportPath destinationpath -exportOptionsPlist path
xcodebuild -exportLocalizations -project name.xcodeproj -localizationPath path [[-exportLanguage language] …]
xcodebuild -importLocalizations -project name.xcodeproj -localizationPath path
挑幾個我常用的形式介紹一下,較長的使用方式以序列號代替:
xcodebuild -showsdks: 列出 Xcode 所有可用的 SDKs
xcodebuild -showBuildSettings: 上述序號6的使用方式枫虏,查看當(dāng)前工程 build setting 的配置參數(shù)辣恋,Xcode 詳細(xì)的 build setting 參數(shù)參考官方文檔 Xcode Build Setting Reference, 已有的配置參數(shù)可以在終端中以 buildsetting=value的形式進(jìn)行覆蓋重新設(shè)置.
xcodebuild -list: 上述序號7的使用方式模软,查看 project 中的 targets 和 configurations伟骨,或者 workspace 中 schemes, 輸出如下:
xcodebuild [-project name.xcodeproj] [[-target targetname] ... | -alltargets] build: 上述序號1的使用方式,會 build 指定 project燃异,其中 -target和 -configuration 參數(shù)可以使用 xcodebuild -list
獲得携狭,-sdk參數(shù)可由 xcodebuild -showsdks獲得[buildsetting=value ...]用來覆蓋工程中已有的配置』乩可覆蓋的參數(shù)參考官方文檔 Xcode Build Setting Reference,
action...的可用選項如下, 打包的話當(dāng)然用 build逛腿,這也是默認(rèn)選項。build
Build the target in the build root (SYMROOT). This is the default action, and is used if no action is given.analyze
Build and analyze a target or scheme from the build root (SYMROOT). This requires specifying a scheme.archive
Archive a scheme from the build root (SYMROOT). This requires specifying a scheme.test
Test a scheme from the build root (SYMROOT). This requires specifying a scheme and optionally a destination.installsrc
Copy the source of the project to the source root (SRCROOT).install
Build the target and install it into the target’s installation directory in the distribution root (DSTROOT).clean
Remove build products and intermediate files from the build root (SYMROOT).xcodebuild -workspace name.xcworkspace -scheme schemename build: 上述序號3的使用方式仅颇,build 指定 workspace单默,當(dāng)我們使用 CocoaPods 來管理第三方庫時,會生成 xcworkspace 文件忘瓦,這樣就會用到這種打包方式.
使用xcodebuild和xcrun打包簽名
開始之前搁廓,可以新建一個測試工程 TestImg 來練習(xí)打包,在使用終端命令打包之前,請確認(rèn)該工程也可以直接使用 Xcode 真機(jī)調(diào)試成功境蜕。
然后蝙场,打開終端,進(jìn)入包含 TestImg.xcodeproj 的目錄下粱年,運(yùn)行以下命令:
xcodebuild -project TestImg.xcodeproj -target TestImg -configuration Release
如果 build 成功售滤,會看到 ** BUILD SUCCEEDED **
字樣,且在終端會打印出這次 build 的簽名信息台诗,如下:
Signing Identity: “iPhone Developer: xxx(59xxxxxx)”
Provisioning Profile: “iOS Team Provisioning Profile: *"
且在該目錄下會多出一個 build目錄完箩,該目錄下有 Release-iphoneos和 TestImg.build文件,根據(jù)我們 build -configuration配置的參數(shù)不同拉队,Release-iphoneos的文件名會不同嗜憔。
在 Release-iphoneos文件夾下,有我們需要的TestImg.app文件氏仗,但是要安裝到真機(jī)上吉捶,我們需要將該文件導(dǎo)出為ipa文件,這里使用 xcrun 命令皆尔。
xcrun -sdk iphoneos -v PackageApplication ./build/Release-iphoneos/TestImg.app -o ~/Desktop/TestImg.ipa
這里又冒出一個 PackageApplication, 我剛開始也不知道這是個什么玩意兒呐舔,萬能的google告訴我,這是 Xcode 包里自帶的工具慷蠕,使用 xcrun -sdk iphoneos -v PackageApplication -help
查看幫助信息.
Usage:
PackageApplication [-s signature] application [-o output_directory] [-verbose] [-plugin plugin] || -man || -help
Options:
[-s signature]: certificate name to resign application before packaging
[-o output_directory]: specify output filename
[-plugin plugin]: specify an optional plugin
-help: brief help message
-man: full documentation
-v[erbose]: provide details during operation
將打包過程腳本化
工作中珊拼,特別是所做項目進(jìn)入測試階段,肯定會經(jīng)常打 Ad-hoc 包給測試人員進(jìn)行測試流炕,但是我們肯定不想每次進(jìn)行打包的時候都要進(jìn)行一些工程的設(shè)置修改澎现,以及一系列的 next 按鈕點(diǎn)擊操作,現(xiàn)在就讓這些操作都交給腳本化吧每辟。
腳本化中使用如下的命令打包:
xcodebuild -project name.xcodeproj -target targetname -configuration Release -sdk iphoneos build CODE_SIGN_IDENTITY="$(CODE_SIGN_IDENTITY)" PROVISIONING_PROFILE="$(PROVISIONING_PROFILE)"
或者
xcodebuild -workspace name.xcworkspace -scheme schemename -configuration Release -sdk iphoneos build CODE_SIGN_IDENTITY="$(CODE_SIGN_IDENTITY)" PROVISIONING_PROFILE="$(PROVISIONING_PROFILE)"
然后使用 xcrun 生成 ipa 文件:
`xcrun -sdk iphoneos -v PackageApplication ./build/Release-iphoneos/$(target|scheme).app"
清除 build 過程中產(chǎn)生的中間文件
結(jié)合蒲公英分發(fā)平臺剑辫,將 ipa 文件上傳至蒲公英分發(fā)平臺,同時在終端會打印上傳結(jié)果以及上傳應(yīng)用后該應(yīng)用的 URL渠欺。蒲公英分發(fā)平臺能夠方便地將 ipa 文件盡快分發(fā)到測試人員妹蔽,該平臺有開放 API,可避免人工上傳挠将。
該腳本的使用可使用 python autobuild.py -h
查看胳岂,與 xcodebuild
的使用相似:
Usage: autobuild.py [options]
Options:
-h, --help: show this help message and exit
-w name.xcworkspace, --workspace=name.xcworkspace: Build the workspace name.xcworkspace.
-p name.xcodeproj, --project=name.xcodeproj: Build the project name.xcodeproj.
-s schemename, --scheme=schemename: Build the scheme specified by schemename. Required if building a workspace.
-t targetname, --target=targetname: Build the target specified by targetname. Required if building a project.
-o output_filename, --output=output_filename: specify output filename
在腳本頂部,有幾個全局變量舔稀,根據(jù)自己的項目情況修改乳丰。
CODE_SIGN_IDENTITY = "iPhone Distribution: companyname (9xxxxxxx9A)"
PROVISIONING_PROFILE = "xxxxx-xxxx-xxx-xxxx-xxxxxxxxx"
CONFIGURATION = "Release"
SDK = "iphoneos"
USER_KEY = "15d6xxxxxxxxxxxxxxxxxx"
API_KEY = "efxxxxxxxxxxxxxxxxxxxx"
其中,CODE_SIGN_IDENTITY為開發(fā)者證書標(biāo)識内贮,可以在 Keychain Access -> Certificates -> 選中證書右鍵彈出菜單 -> Get Info -> Common Name 獲取产园,類似 iPhone Distribution: Company name Co. Ltd (xxxxxxxx9A), 包括括號內(nèi)的內(nèi)容汞斧。
PROVISIONING_PROFILE: 這個是 mobileprovision 文件的 identifier,獲取方式:Xcode -> Preferences -> 選中申請開發(fā)者證書的 Apple ID -> 選中開發(fā)者證書 -> View Details… -> 根據(jù) Provisioning Profiles 的名字選中打包所需的 mobileprovision 文件 -> 右鍵菜單 -> Show in Finder -> 找到該文件后淆两,除了該文件后綴名的字符串是 PROVISIONING_PROFILE 字段的內(nèi)容。
當(dāng)然也可以使用腳本獲取, 此處參考 命令行獲取mobileprovision文件的UUID:
#!/bin/bash
if [ $# -ne 1 ]
then
echo "Usage: getmobileuuid the-mobileprovision-file-path"
exit 1
fi
mobileprovision_uuid=`/usr/libexec/PlistBuddy -c "Print UUID" /dev/stdin <<< $(/usr/bin/security cms -D -i $1)
`echo "UUID is:
"echo ${mobileprovision_uuid}
USER_KEY, API_KEY: 是蒲公英開放 API 的密鑰拂酣。