因?yàn)樾枰罱谘芯坑媚_本編譯.ipa文件,在網(wǎng)上查找了不少資料,發(fā)現(xiàn)都是一些比較舊的操作了,在應(yīng)用的時(shí)候難免會(huì)有一些問(wèn)題。不過(guò)綜合網(wǎng)上的各種說(shuō)法和蘋果最新的官方文檔還是得到一個(gè)最終結(jié)果,記錄下來(lái),方便日后的使用。
1. 工具
- xcodebuild簡(jiǎn)介
xcodebuild
是蘋果提供的打包項(xiàng)目或者工程的命令,可以使用man xcodebuild
或者xcodebuild -help
來(lái)了解該命令的具體操作與用法。
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.
- xcodebuild用法
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 -list:可以查看Targets、Schemes、以及Configuration,這幾個(gè)參數(shù)會(huì)在后續(xù)操作中用到。
- xcodebuild -showsdks:查看Xcode 所有可用的 SDKs信息。
-
xcodebuild -showBuildSettings:查看project所有的配置信息,已有的配置參數(shù)可以在build時(shí)添加
buildsetting=value
進(jìn)行覆蓋重新設(shè)置。 - xcodebuild [-project name.xcodeproj] -scheme:build指定的project。
- xcodebuild -workspace name.xcworkspace -scheme:build 指定 workspace,與上一條功能相同,看到有人說(shuō)用到CocoaPod時(shí)會(huì)生成.xcworkspace文件,故而需要采用該方法。但是我發(fā)現(xiàn)沒(méi)有使用CocoaPod時(shí),也可以找到xxx.xcodeproj/project.xcworkspace文件,也可以使用該方法,而且得到的結(jié)果和第3條并沒(méi)有什么差異。對(duì)此,本人還沒(méi)什么深入研究,知道詳情的大牛可以解釋下當(dāng)然更好啦~~~
- xcodebuild -exportArchive -archivePath:打包生成.ipa文件,需要在上述3/4步操作后執(zhí)行。
注:在第3/4條操作時(shí),需要添加一個(gè)參數(shù)[action ...]
,該參數(shù)有如下幾種選擇:
Specify one or more actions to perform. Available actions are:
build
Build the target in the build root (SYMROOT). This is the default action, and is used if no action is given.
build-for-testing
Build the target and associated tests in the build root (SYMROOT). This will also produce an xctestrun file in the build root. This requires specifying a scheme.
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.
test-without-building
Test compiled bundles. If a scheme is provided with -scheme then the command finds bundles in the build root (SRCROOT). If an xctestrun file is provided with -xctestrun then the command finds bundles at paths specified in the xctestrun file.
install-src
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之后的內(nèi)容涉及兩種用法,ie:xcodebuild -project xxx.xcodeproj -scheme xxx clean build -showsdks
。當(dāng)出現(xiàn)這種情況時(shí),編譯器只會(huì)執(zhí)行后一種用法,也就是說(shuō)示例中的操作在終端中執(zhí)行后,不會(huì)build project,只會(huì)輸出SDKs的信息。
2. 實(shí)現(xiàn)
- 舊方法
首先說(shuō)一下找到的第一種方法,試了一下,確實(shí)是可以編出ipa包的,安裝之后似乎也沒(méi)有什么問(wèn)題,至少生成的ipa文件安裝到手機(jī)上之后APP的功能都運(yùn)行正常。
該方法的操作是:切換到項(xiàng)目xxx.xcodeproj所在文件夾下,并在終端執(zhí)行以下兩句
$ xcodebuild -project 'xxx.xcodeproj' -target 'xxx' -configuration 'Release' -sdk 'iphoneos' build
$ xcrun -sdk 'iphoneos' -v PackageApplication './build/Release-iphoneos/xxx.app' -o '~/Desktop/xxx.ipa'
注:其中,單引號(hào)標(biāo)示的內(nèi)容是需要按照自己的項(xiàng)目進(jìn)行更換的。
但是該方法主要的問(wèn)題是,成功之后會(huì)有一條警告信息:
warning: PackageApplication is deprecated, use `xcodebuild -exportArchive` instead.
既然已經(jīng)提示該方法被廢棄,并由其他方法所替代,所以暫時(shí)就不考慮該方法了。
- 當(dāng)前最新方法
接下來(lái)就是按照提示去查找最新可用的方法了。現(xiàn)在測(cè)試,該操作是可以成功編譯出.ipa文件,并且安裝之后APP操作都運(yùn)行正常,最重要的是編譯的時(shí)候沒(méi)有要命的警告_。
該方法的操作是:切換到項(xiàng)目xxx.xcodeproj所在文件夾下,并在終端執(zhí)行以下兩句
$ xcodebuild -project 'xxx.xcodeproj' -scheme 'xxx' -configuration 'Release' -arch 'arm64' archive -archivePath '$PWD/build/xxx.xcarchive'
$ xcodebuild -exportArchive -archivePath '$PWD/build/xxx.xcarchive' -exportOptionsPlist 'export.plist' -exportPath '$PWD/build'
注:其中,單引號(hào)標(biāo)示的內(nèi)容是需要按照自己的項(xiàng)目進(jìn)行更換的。
在第一步操作結(jié)束后,會(huì)看到** BUILD SUCCEEDED **
信息,表示編譯成功。同時(shí),向上拖動(dòng)一段輸出信息,可以看到以下兩句信息:
Signing Identity: "iPhone Developer: UserName (User-Id)"
Provisioning Profile: "iOS Team Provisioning Profile: Bundle-Id"
(b1xxxx-xxxx-xxxx-xxxx-xxxxxx)
該信息是文件的簽名信息,可以在第一步中以buildsetting=value
的方式進(jìn)行設(shè)置,具體內(nèi)容可以在Keychain Access -> Certificates -> 選中iPhone Developer:UserName(User-Id)證書(shū)右鍵彈出菜單 -> Get Info 中獲取。
注:該操作中最重要的一點(diǎn)是對(duì)于export.plist
文件的配置,查看官方文檔,里邊有一段說(shuō)明:
Available keys for -exportOptionsPlist:
compileBitcode : Bool
For non-App Store exports, should Xcode re-compile the app from bitcode? Defaults to YES.
embedOnDemandResourcesAssetPacksInBundle : Bool
For non-App Store exports, if the app uses On Demand Resources and this is YES, asset packs are embedded in the app bundle so that the app can be tested without a server to host asset packs. Defaults to YES unless onDemandResourcesAssetPacksBaseURL is specified.
iCloudContainerEnvironment
For non-App Store exports, if the app is using CloudKit, this configures the "com.apple.developer.icloud-container-environment" entitlement. Available options: Development and Production. Defaults to Development.
manifest : Dictionary
For non-App Store exports, users can download your app over the web by opening your distribution manifest file in a web browser. To generate a distribution manifest, the value of this key should be a dictionary with three sub-keys: appURL, displayImageURL, fullSizeImageURL. The additional sub-key assetPackManifestURL is required when using on demand resources.
method : String
Describes how Xcode should export the archive. Available options: app-store, package, ad-hoc, enterprise, development, and developer-id. The list of options varies based on the type of archive. Defaults to development.
onDemandResourcesAssetPacksBaseURL : String
For non-App Store exports, if the app uses On Demand Resources and embedOnDemandResourcesAssetPacksInBundle isn't YES, this should be a base URL specifying where asset packs are going to be hosted. This configures the app to download asset packs from the specified URL.
teamID : String
The Developer Portal team to use for this export. Defaults to the team used to build the archive.
thinning : String
For non-App Store exports, should Xcode thin the package for one or more device variants? Available options: <none> (Xcode produces a non-thinned universal app), <thin-for-all-variants> (Xcode produces a universal app and all available thinned variants), or a model identifier for a specific device (e.g. "iPhone7,1"). Defaults to <none>.
uploadBitcode : Bool
For App Store exports, should the package include bitcode? Defaults to YES.
uploadSymbols : Bool
For App Store exports, should the package include symbols? Defaults to YES.
有很多參數(shù)是不必要的,現(xiàn)在查看teamID和method似乎是比較需要的,寫了一個(gè)示例:
<?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>ad-hoc/enterprise/development</string>
<key>teamID</key>
<string>YOU_DISTRIBUTION_TEAM_ID</string>
<key>compileBitcode</key>//暫不支持bitcode
<string>NO</string>
</dict>
</plist>
因?yàn)槲疫@邊主要是企業(yè)賬號(hào)開(kāi)發(fā),所以method是上述三項(xiàng)三選一。如果是個(gè)人賬號(hào),需要上傳到App Store,需要設(shè)置method=app-store。
關(guān)于TeamID,可以去Keychain Access -> Certificates -> 選中前綴為iPhone Distribution:XXX的證書(shū)右鍵彈出菜單 -> Get Info 中獲取組織ID即可。
3. 腳本文件
我是使用Makefile來(lái)編譯ipa的,存放Makefile文件在xxx.xcodeproj所處文件夾下,然后直接執(zhí)行make來(lái)編譯,主要使用的就是這兩句操作,所以在此就不給文件的示例了。
如果您需要shell腳本執(zhí)行,可以自己寫個(gè).sh腳本哈,主要輸入就是xxx.xcodeproj文件存放路徑和ProjectName兩項(xiàng),其他需求可以針對(duì)不同情況隨時(shí)調(diào)整。本人對(duì)腳本的研究還有點(diǎn)欠缺,就不在此獻(xiàn)丑了。