本文最终实现的是使用脚本打 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 的密钥。