iOS进阶_打包脚本

[TOC]

一、认识Mac的keychain机制

要使用Keychain中的证书,请先unlock-keychain

完整的命令如下:

1
security unlock-keychain -p "lichaoqian" "/Users/lichaoqian/Library/Keychains/login.keychain"

如果你是在Jenkins中执行的,请确保你的权限问题。具体的解决可进入《使用工具->Jenkins->Jenkins使用问题常见》中的”二、权限问题”中查看解决。

其他参考文章:

二、认识几个命令

  • 查看SDK版本
1
xcodebuild -showsdks

查询结果如下:

xcodebuild -showsdks的执行结果

三、认识执行命令

在终端执行xcodebuild --help

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
Beyond-MacBook-Pro:~ lichaoqian$ xcodebuild --help
Usage: xcodebuild [-project <projectname>] [[-target <targetname>]...|-alltargets] [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings [-json]] [<buildsetting>=<value>]... [<buildaction>]...
xcodebuild [-project <projectname>] -scheme <schemeName> [-destination <destinationspecifier>]... [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings [-json]] [-showdestinations] [<buildsetting>=<value>]... [<buildaction>]...
xcodebuild -workspace <workspacename> -scheme <schemeName> [-destination <destinationspecifier>]... [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [-showdestinations] [<buildsetting>=<value>]... [<buildaction>]...
xcodebuild -version [-sdk [<sdkfullpath>|<sdkname>] [-json] [<infoitem>] ]
xcodebuild -list [[-project <projectname>]|[-workspace <workspacename>]] [-json]
xcodebuild -showsdks [-json]
xcodebuild -exportArchive -archivePath <xcarchivepath> [-exportPath <destinationpath>] -exportOptionsPlist <plistpath>
xcodebuild -exportNotarizedApp -archivePath <xcarchivepath> -exportPath <destinationpath>
xcodebuild -exportLocalizations -localizationPath <path> -project <projectname> [-exportLanguage <targetlanguage>...[-includeScreenshots]]
xcodebuild -importLocalizations -localizationPath <path> -project <projectname>
xcodebuild -resolvePackageDependencies [-project <projectname>|-workspace <workspacename>] -clonedSourcePackagesDirPath <path>
xcodebuild -create-xcframework [-help] [-framework <path>] [-library <path> [-headers <path>]] -output <path>

Options:
-usage print brief usage
-help print complete usage
-verbose provide additional status output
-license show the Xcode and SDK license agreements
-checkFirstLaunchStatus Check if any First Launch tasks need to be performed
-runFirstLaunch install packages and agree to the license
-project NAME build the project NAME
-target NAME build the target NAME
-alltargets build all targets
-workspace NAME build the workspace NAME
-scheme NAME build the scheme NAME
-configuration NAME use the build configuration NAME for building each target
-xcconfig PATH apply the build settings defined in the file at PATH as overrides
-arch ARCH build each target for the architecture ARCH; this will override architectures defined in the project
-sdk SDK use SDK as the name or path of the base SDK when building the project
-toolchain NAME use the toolchain with identifier or name NAME
-destination DESTINATIONSPECIFIER use the destination described by DESTINATIONSPECIFIER (a comma-separated set of key=value pairs describing the destination to use)
-destination-timeout TIMEOUT wait for TIMEOUT seconds while searching for the destination device
-parallelizeTargets build independent targets in parallel
-jobs NUMBER specify the maximum number of concurrent build operations
-maximum-concurrent-test-device-destinations NUMBER the maximum number of device destinations to test on concurrently
-maximum-concurrent-test-simulator-destinations NUMBER the maximum number of simulator destinations to test on concurrently
-parallel-testing-enabled YES|NO overrides the per-target setting in the scheme
-parallel-testing-worker-count NUMBER the exact number of test runners that will be spawned during parallel testing
-maximum-parallel-testing-workers NUMBER the maximum number of test runners that will be spawned during parallel testing
-dry-run do everything except actually running the commands
-quiet do not print any output except for warnings and errors
-hideShellScriptEnvironment don't show shell script environment variables in build log
-showsdks display a compact list of the installed SDKs
-showdestinations display a list of destinations
-showTestPlans display a list of test plans
-showBuildSettings display a list of build settings and values
-list lists the targets and configurations in a project, or the schemes in a workspace
-find-executable NAME display the full path to executable NAME in the provided SDK and toolchain
-find-library NAME display the full path to library NAME in the provided SDK and toolchain
-version display the version of Xcode; with -sdk will display info about one or all installed SDKs
-enableAddressSanitizer YES|NO turn the address sanitizer on or off
-enableThreadSanitizer YES|NO turn the thread sanitizer on or off
-enableUndefinedBehaviorSanitizer YES|NO turn the undefined behavior sanitizer on or off
-resultBundlePath PATH specifies the directory where a result bundle describing what occurred will be placed
-resultStreamPath PATH specifies the file where a result stream will be written to (the file must already exist)
-resultBundleVersion 3 [default] specifies which result bundle version should be used
-clonedSourcePackagesDirPath PATH specifies the directory to which remote source packages are fetch or expected to be found
-derivedDataPath PATH specifies the directory where build products and other derived data will go
-archivePath PATH specifies the directory where any created archives will be placed, or the archive that should be exported
-exportArchive specifies that an archive should be exported
-exportNotarizedApp export an archive that has been notarized by Apple
-exportOptionsPlist PATH specifies a path to a plist file that configures archive exporting
-enableCodeCoverage YES|NO turn code coverage on or off when testing
-exportPath PATH specifies the destination for the product exported from an archive
-skipUnavailableActions specifies that scheme actions that cannot be performed should be skipped instead of causing a failure
-exportLocalizations exports completed and outstanding project localizations
-importLocalizations imports localizations for a project, assuming any necessary localized resources have been created in Xcode
-localizationPath specifies a path to XLIFF localization files
-exportLanguage specifies multiple optional ISO 639-1 languages included in a localization export
-xctestrun specifies a path to a test run specification
-testPlan specifies the name of the test plan associated with the scheme to use for testing
-only-testing constrains testing by specifying tests to include, and excluding other tests
-only-testing:TEST-IDENTIFIER constrains testing by specifying tests to include, and excluding other tests
-skip-testing constrains testing by specifying tests to exclude, but including other tests
-skip-testing:TEST-IDENTIFIER constrains testing by specifying tests to exclude, but including other tests
-only-test-configuration constrains testing by specifying test configurations to include, and excluding other test configurations
-skip-test-configuration constrains testing by specifying test configurations to exclude, but including other test configurations
-testLanguage constrains testing by specifying ISO 639-1 language in which to run the tests
-testRegion constrains testing by specifying ISO 3166-1 region in which to run the tests
-resolvePackageDependencies resolves any Swift package dependencies referenced by the project or workspace
-disableAutomaticPackageResolution prevents packages from automatically being resolved to versions other than those recorded in the `Package.resolved` file
-json output as JSON (note: -json implies -quiet)
-allowProvisioningUpdates Allow xcodebuild to communicate with the Apple Developer website. For automatically signed targets, xcodebuild will create and update profiles, app IDs, and certificates. For manually signed targets, xcodebuild will download missing or updated provisioning profiles. Requires a developer account to have been added in Xcode's Accounts preference pane.
-allowProvisioningDeviceRegistration Allow xcodebuild to register your destination device on the developer portal if necessary. This flag only takes effect if -allowProvisioningUpdates is also passed.
-showBuildTimingSummary display a report of the timings of all the commands invoked during the build
-create-xcframework create an xcframework from prebuilt libraries; -help for more information.

Available keys for -exportOptionsPlist:

compileBitcode : Bool

For non-App Store exports, should Xcode re-compile the app from bitcode? Defaults to YES.

destination : String

Determines whether the app is exported locally or uploaded to Apple. Options are export or upload. The available options vary based on the selected distribution method. Defaults to export.

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.

generateAppStoreInformation : Bool

For App Store exports, should Xcode generate App Store Information for uploading with iTMSTransporter? Defaults to NO.

iCloudContainerEnvironment : String

If the app is using CloudKit, this configures the "com.apple.developer.icloud-container-environment" entitlement. Available options vary depending on the type of provisioning profile used, but may include: Development and Production.

installerSigningCertificate : String

For manual signing only. Provide a certificate name, SHA-1 hash, or automatic selector to use for signing. Automatic selectors allow Xcode to pick the newest installed certificate of a particular type. The available automatic selectors are "Mac Installer Distribution" and "Developer ID Installer". Defaults to an automatic certificate selector matching the current distribution method.

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, validation, ad-hoc, package, enterprise, development, developer-id, and mac-application. 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.

provisioningProfiles : Dictionary

For manual signing only. Specify the provisioning profile to use for each executable in your app. Keys in this dictionary are the bundle identifiers of executables; values are the provisioning profile name or UUID to use.

signingCertificate : String

For manual signing only. Provide a certificate name, SHA-1 hash, or automatic selector to use for signing. Automatic selectors allow Xcode to pick the newest installed certificate of a particular type. The available automatic selectors are "Mac App Distribution", "iOS Distribution", "iOS Developer", "Developer ID Application", "Apple Distribution", "Mac Developer", and "Apple Development". Defaults to an automatic certificate selector matching the current distribution method.

signingStyle : String

The signing style to use when re-signing the app for distribution. Options are manual or automatic. Apps that were automatically signed when archived can be signed manually or automatically during distribution, and default to automatic. Apps that were manually signed when archived must be manually signed during distribtion, so the value of signingStyle is ignored.

stripSwiftSymbols : Bool

Should symbols be stripped from Swift libraries in your IPA? Defaults to YES.

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.

1、cd到代码目录

2、开始打包

  • 执行命令

写在终端进行测试的命令:

1
xcodebuild -workspace CJAutoPackageDemo.xcworkspace -scheme App1Enterprise -configuration Debug -sdk iphoneos12.2 ARCHS='arm64 armv7' IOS_DEVELOPMENT_TARGET=8.0 -derivedDataPath ../output/build/Debug-iphoneos archive -archivePath ../output/Debug-iphoneos/App1Enterprise.xcarchive

写在脚本中的命令:

1
2
3
4
5
echo ""
echo ""
echo ">>>>>>>>>>>>>>>>>>>>>>>>>> step5:begin compile project >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
xcodebuild -workspace ${PROJECT_DIR}/${APPPROJECT_NAME}.xcworkspace -scheme ${APPTARGET_NAME} -configuration ${BUILD_CONFIGURATION_NAME} -sdk ${SIMULATOR_OR_IOS_SDK}${SDK_VERSION} ARCHS='arm64 armv7' IOS_DEVELOPMENT_TARGET=${DEVELOPMENT_TARGET} -derivedDataPath ${BUILD_OUTPUT_PATH} archive -archivePath "${ARCHIVE_OUTPUT_PATH}/${APPTARGET_NAME}.xcarchive"
echo "<<<<<<<<<<<<<<<<<<<<<<<<<<< step5:end compile project <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"

参数介绍:

参数 含义
-workspace 工程文件名(用cocopods集成的项目,没有的话 整个改为-xcodeproj xxx.xcodeproj)
-scheme 通过scheme指定不同的target
-configuration 对应的环境配置,就是编译的时候执行的模式
(测试Debug、预生产PreRelease、生产Release)
-archivePath 导出的.xcarchive的路径
-sdk
-derivedDataPath
-archivePath 导出的.xcarchive的路径

3、导出ipa

  • 执行命令
1
2
3
4
5
6
7
8
9
10
11
echo ""
echo ""
echo ">>>>>>>>>>>>>>>>>>>>>>>>>> step6:begin archiving app to ipa >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo "PWD=$PWD"
cd ${ROOT_DIR}
echo "PWD=$PWD"
echo "archivePath ==>>> ${ARCHIVE_OUTPUT_PATH}/${APPTARGET_NAME}.xcarchive"
echo "exportPath ==>>> ${ARCHIVE_OUTPUT_PATH}/${APPTARGET_NAME}"
echo "exportOptionsPlist ==>>> ${ExportOptionsPlist_PATH}"
xcodebuild -exportArchive -archivePath "${ARCHIVE_OUTPUT_PATH}/${APPTARGET_NAME}.xcarchive" -exportPath "${ARCHIVE_OUTPUT_PATH}/${APPTARGET_NAME}" -exportOptionsPlist "${ExportOptionsPlist_PATH}" -allowProvisioningUpdates
echo "<<<<<<<<<<<<<<<<<<<<<<<<<<< step6:end archiving app to ipa <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
  • 参数解读:
参数 含义
-archivePath .xcarchive文件的路径
-exportPath 导出的ipa的路径
-exportOptionsPlist

三、完整脚本内容(含使用Jenkins打包)

  • 测试项目工程详见:gitee中的AutoPackage-iOS工程

  • 测试Jenkins工程详见:本地Jenkins中的CJAutoPackage工程

  • 最终Jenkins脚本如下图:

    iOS打包_Jenkins脚本

附:没有权限问题的Jenkins正确的启动方式如下(按下面方式打开,才不会出现权限问题):

1
2
$ sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist
$ java -jar /Applications/Jenkins/jenkins.war --httpPort=8080

当你执行完这两行命令的时候,你可以在浏览器上输入http://localhost:8080来访问Jenkins了。(如果你只执行了第一行,没执行第二行,会出现无法访问)

更多Jenkins知识请查看:实用工具->Jenkins->Jenkins的安装与启动

四、注意点

1、多环境的打包

主要注意为xcodebuild -workspace中的-configuration参数即可。

2、多Target的打包注意

多Target的Podfile文件ruby脚本内容,大概如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
source 'https://github.com/CocoaPods/Specs.git'
source 'https://gitee.com/dvlproad/dvlproadSpecs'

platform :ios, '8.0'
#use_frameworks!
inhibit_all_warnings!

post_install do |installer|

puts 'Determining pod project minimal deployment target'

pods_project = installer.pods_project
deployment_target_key = 'IPHONEOS_DEPLOYMENT_TARGET'
deployment_targets = pods_project.build_configurations.map{ |config| config.build_settings[deployment_target_key] }
minimal_deployment_target = deployment_targets.min_by{ |version| Gem::Version.new(version) }

puts 'Minimal deployment target is ' + minimal_deployment_target
puts 'Setting each pod deployment target to ' + minimal_deployment_target

installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings[deployment_target_key] = minimal_deployment_target
end
end
end


# There are no targets called "App1Common" in any Xcode projects
abstract_target 'App1Common' do
# Has its own copy of App1Common + App1Enterprise
target 'App1Enterprise' do

end

# Has its own copy of App1Common + App1AppStore
target 'App1AppStore' do

end
end



target 'CJAutoPackageDemoTests' do

end

通过脚本自动化打包的时候的注意点如下:

  1. 主要注意为xcodebuild -workspace中的-scheme参数即可。

  2. 多Target后,记得在Linked Frameworks and Libraries中删除已经不存在的原本旧的libPods-xxx.a文件。否则,Jenkins脚本打包Build的时候会报错。

    • Jenkins脚本打包Build的时候报错的信息如下:

    Jenkins脚本打包Build的时候报错的信息

    • 多Target工程打包时候要删除的旧引用文件如下:

      多Target工程打包时候要删除的旧引用文件