写在最前头
开发周期内的应用基本每天都会使用Xcode打包ipa,上传到fir进行测试,这样基本每次都要花费十几分钟如果遇到证书问题可能会更久这样日复一日月复一月年复一年的做着同样的事情烦死了,所以决定使用自动化解决问题。
简介
xcodebuild 是苹果发布自动构建的工具。它在一个Xcode项目下能构建一个或者多个targets ,也能在一个workspace或者Xcode项目上构建scheme
用法说明
在终端输入man xcodebuild,可以看到Description里面有介绍用法。
也可以自行研究官方文档
接下来主要说明使用arhive和exportArchive来打包(由于我们的工程主要使用CocoaPods做第三方库的依赖的管理工具,所以一下默认工程使用Pod)
Archive打包方法
先看命令:
xcodebuild archive -workspace 项目名称.xcworkspace
-scheme 项目名称
-configuration 构建配置
-archivePath archive包存储路径
CODE_SIGN_IDENTITY=证书
PROVISIONING_PROFILE=描述文件UUID
>> $log_path
注解:
1、-workspace 这个字段就是项目名
2、-scheme 可以通过xcodebuild -list获取
3、-configuration 可以通过xcodebuild -list获取
4、-archivePath archive后的路径
5、CODE_SIGN_IDENTITY 证书的Inentity
6、PROVISIONING_PROFILE 描述文件UUID
7、$log_path 日志文件位置(可选,一般终端运行傻子才选 脚本运行傻子不选☺)
xcodebuild -list 命令结果(一目了然):
Information about project "red-envelope-iOS":
Targets:
red-envelope-iOS
Build Configurations:
Debug
Release
If no build configuration is specified and -scheme is not passed then "Release" is used.
Schemes:
red-envelope-iOS
如果不指定证书和Provisioning文件最后两个参数可以不进行设置(会根据你的Xcode配置去匹配),那么想自行设置怎么获取这两个参数呢?
获取证书的Inentity:
打开你的钥匙串访问->选中其中一个证书->右键->显示简介,把标题复制出来就可以了
描述文件UUID:
Provisioning文件位置
/Users/iSailor(用户名)/Library/MobileDevice/Provisioning Profiles
从终端进入上面这个文件夹;使用/usr/bin/security可以把Provisioning文件解密
/usr/bin/security cms -D -i 01df6c02-5c3f-42f1-aa8f-af6f283435ff.mobileprovision
在终端输出整个plist文件,里面包含着所有的信息
导出ipa包
先看命令:
xcodebuild -exportArchive -archivePath archive文件的地址.xcarchive
-exportPath 导出的文件夹地址
-exportOptionsPlist exprotOptionsPlist.plist
CODE_SIGN_IDENTITY=证书
PROVISIONING_PROFILE=描述文件UUID
>> $log_path
注解:
1、-archivePath 上一节中生成的.xcarchive文件位置
2、-exportPath 导出的文件夹地址(也就是ipa文件夹位置)
3、-exportOptionsPlist 它是一个plist文件
4、CODE_SIGN_IDENTITY 证书的Inentity
5、PROVISIONING_PROFILE 描述文件UUID
7、$log_path 日志文件位置(同上)
exprotOptionsPlist.plist文件:
<?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>teamID</key>
<string>RJ5C7D2C4E</string>
<key>method</key>
<string>development</string>
<key>compileBitcode</key>
<false/>
</dict>
</plist>
Available keys for -exportOptionsPlist:
method(导出ipa包类型)这个字段对应的值 : String
app-store, ad-hoc, enterprise, development, developer-id
Describes how Xcode should export the archive. Available options: app-store, ad-hoc, package, enterprise, development, and developer-id. The list of options varies based on the type of archive. Defaults to development.
compileBitcode : Bool
位编码是否启用 非appstore应用使用,默认是YES
For non-App Store exports, should Xcode re-compile the app from bitcode? Defaults to YES.
embedOnDemandResourcesAssetPacksInBundle : Bool
非appstore应用使用,默认是YES
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 : String
Development, Production
non-App Store应用,默认Development,如果使用icloud需要打开
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
non-App Store应用
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.
onDemandResourcesAssetPacksBaseURL : String
non-App Store应用,用来下载资源
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
用来打包的temID
The Developer Portal team to use for this export. Defaults to the team used to build the archive.
thinning : String
non-App Store应用,默认 <none> ,通用设备
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
默认 YES
For App Store exports, should the package include bitcode? Defaults to YES.
uploadSymbols : Bool
默认YES
For App Store exports, should the package include symbols? Defaults to YES.
上传到Fir
在终端安装fir-cli一个命令即可:
gem install fir-cli
相对简单些,可以参考官方文档
先看命令:
fir publish ipa地址
-T ApiToken
-s 短连接
-c 更改日志
-Q 是否生成发布后二维码
>> $log_path
注解:
1、-T 用户在 fir.im 上的 api_token
2、-s 自定义发布后的短链接地址
3、-c 自定义发布更改日志
4、-Q 是否生成发布后二维码
5、$log_path 日志文件位置(同上)
案例
#!/bin/sh
# 当前目录
pwd=$PWD
echo "+++++++ 当前目录: $pwd ++++++"
# 获取参数
describe=$1
# 名称配置
checkout_name="red-envelope-iOS"
project_name="red-envelope-iOS"
# 项目版本配置
targetProject_sdk="iphoneos8.0"
targetProject_destination="generic/platform=iOS"
configuration="Debug"
scheme="$project_name"
workspace_name="${project_name}.xcworkspace"
# 目录配置
save_path="$pwd/uploadIPA"
archive_path="$save_path/${project_name}.xcarchive"
ipa_path="$save_path/${project_name}"
log_path="$save_path/log.txt"
# 配置Fir
upload_path="$ipa_path/${project_name}.ipa"
fir_apiToken="4d3f304049be126ea04268d8677a6c48"
# 证书描述文件配置
code_sign_identity="iPhone Distribution: Hangzhou Jiuzang Network Technology Co.,Ltd (8KG48SSW8B)"
# code_sign_identity="iPhone Developer: Fangquan Zhang (94763T8SV4)"
uuid="01df6c02-5c3f-42f1-aa8f-af6f283435ff"
profile="redpackets_dev"
# 打包目录
echo "+++++++ 进入指定目录 ++++++"
build_path="$pwd/$project_name"
# 重要,执行xcodebuild命令时,必须进入项目目录
cd "$build_path" >> $log_path
# 开始打包
echo "++++++ 正在打包 ++++++"
xcodebuild archive -workspace "$workspace_name" -scheme "$scheme" -configuration "$configuration" -archivePath "$archive_path" >> $log_path
echo "++++++ 正在导出ipa包 ++++++"
# 导出IPA CODE_SIGN_IDENTITY="$code_sign_identity" PROVISIONING_PROFILE="$uuid"
xcodebuild -exportArchive -archivePath "$archive_path" -exportPath "$ipa_path" -exportOptionsPlist exprotOptionsPlist.plist -allowProvisioningUpdates >> $log_path
echo "++++++ 正在上传ipa到Fir ++++++"
# 上传IPA到Fir
fir publish "$upload_path" -T "$fir_apiToken" -s "redenvelope" -c "$describe" -Q >> $log_path