本文最終實現的是使用腳本打 Ad-hoc 包,併發布測試,固然稍微修改一下腳本參數就能夠打其餘類型的 ipa 包了。另外該腳本還實現了將生成的 ipa 包上傳至蒲公英進行測試分發。文中內容包括:ios
xcodebuild
是蘋果提供的打包項目或者工程的命令,瞭解該命令最好的方式就是使用 man xcodebuild
查看其 man page. 儘管是英文,必定要老老實實的讀一遍就行了。xcode
DESCRIPTIONbash
xcodebuild builds one or more targets contained in an Xcode project, or builds a scheme contained in an Xcode workspace or Xcode project.併發
Usageapp
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.iphone
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.ide
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.工具
總結一下:測試
xcodebuild
命令,且若是該目錄下有多個 projects,那麼須要使用 -project
指定須要 build 的項目。-workspace
和 -scheme
參數,scheme 參數控制了哪些 targets 會被 build 以及以怎樣的方式 build。-list
, -showBuildSettings
, -showsdks
的參數能夠查看項目或者工程的信息,不會對 build action 形成任何影響,放心使用。那麼,xcodebuild
究竟如何使用呢? 繼續看文檔:ui
NAME
xcodebuild – build Xcode projects and workspaces
SYNOPSIS
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的使用方式,查看當前工程 build setting 的配置參數,Xcode 詳細的 build setting 參數參考官方文檔 Xcode Build Setting Reference, 已有的配置參數能夠在終端中以 buildsetting=value
的形式進行覆蓋從新設置.
xcodebuild -list
: 上述序號7的使用方式,查看 project 中的 targets 和 configurations,或者 workspace 中 schemes, 輸出以下:
Information about project "NavTabBar": Targets: NavTabBar NavTabBarTests NavTabBarUITests Build Configurations: Debug Release Ad-hoc If no build configuration is specified and -scheme is not passed then "Release" is used. Schemes: NavTabBar
xcodebuild [-project name.xcodeproj] [[-target targetname] ... | -alltargets] build
: 上述序號1的使用方式,會 build 指定 project,其中 -target
和 -configuration
參數可使用 xcodebuild -list
得到,-sdk
參數可由 xcodebuild -showsdks
得到,[buildsetting=value ...]
用來覆蓋工程中已有的配置。可覆蓋的參數參考官方文檔 Xcode Build Setting Reference, action...
的可用選項以下, 打包的話固然用 build,這也是默認選項。
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,當咱們使用 CocoaPods 來管理第三方庫時,會生成 xcworkspace 文件,這樣就會用到這種打包方式.
開始以前,能夠新建一個測試工程 TestImg 來練習打包,在使用終端命令打包以前,請確認該工程也能夠直接使用 Xcode 真機調試成功。
而後,打開終端,進入包含 TestImg.xcodeproj 的目錄下,運行如下命令:
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
文件,根據咱們 build -configuration
配置的參數不一樣,Release-iphoneos
的文件名會不一樣。
在 Release-iphoneos
文件夾下,有咱們須要的TestImg.app
文件,可是要安裝到真機上,咱們須要將該文件導出爲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 || -helpOptions:
[-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
若是執行成功,則會在你的桌面生成 TestImg.ipa 文件,這樣就能夠發佈測試了。若是你遇到如下警告信息:
Warning: –resource-rules has been deprecated in Mac OS X >= 10.10! ResourceRules.plist: cannot read resources
請參考 stackoverflow 這個
工做中,特別是所作項目進入測試階段,確定會常常打 Ad-hoc 包給測試人員進行測試,可是咱們確定不想每次進行打包的時候都要進行一些工程的設置修改,以及一系列的 next 按鈕點擊操做,如今就讓這些操做都交給腳本化吧。
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 -sdk iphoneos -v PackageApplication ./build/Release-iphoneos/$(target|scheme).app」
該腳本的使用可以使用 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
在腳本頂部,有幾個全局變量,根據本身的項目狀況修改。
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
爲開發者證書標識,能夠在 Keychain Access -> Certificates -> 選中證書右鍵彈出菜單 -> Get Info -> Common Name 獲取,相似 iPhone Distribution: Company name Co. Ltd (xxxxxxxx9A)
, 包括括號內的內容。
PROVISIONING_PROFILE
: 這個是 mobileprovision 文件的 identifier,獲取方式:
Xcode -> Preferences -> 選中申請開發者證書的 Apple ID -> 選中開發者證書 -> View Details… -> 根據 Provisioning Profiles 的名字選中打包所需的 mobileprovision 文件 -> 右鍵菜單 -> Show in Finder -> 找到該文件後,除了該文件後綴名的字符串就是 PROVISIONING_PROFILE
字段的內容。
固然也可使用腳本獲取, 此處參考 命令行獲取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 的密鑰。