MG--iOS自动化脚本打包(小总结)

Mac Xcode版本切换

显示当前哪个Xcode负责打包,在shell中输入:

sudo xcode-select -p

也可以在Xcode中查看


image.png

切换Xcode版本去打包

sudo xcode-select -s /Applications/Xcode.app/Contents/Developer

查看当前Xcode版本

gcc --version






一、配置自动打包发布的流程

1、创建Shell脚本
2、将Shell脚本文件拖入工程的根目录
3、根据自己需求选择好描述文件(测试包或是正式包)
4、根据自己的项目修改一下shell.sh
5、cd到工程根目录,通过./shell.sh 执行脚本即可

将通过这几步来讲解整个过程

准备工作
准备工作做完后,正式开启自动化之路

准备工作

  • 1、终端执行 gem install fir-cli

    因为要上传到Fir平台,需要先安装fir-cli


    安装fir-cli.png
  • 2、安装RVM

如果没有安装过rvm,需要安装rvm,在终端输入rvm -v命令查看,如果打印出rvm:command not found说明没有安装过rvm,如果能打印出rvm版本等信息说明安装过。如果没有安装过rvm可以通过下面的命安装,如果已经安装过可以忽略。

在终端输入 curl -L get.rvm.io | bash -s stable ,然后稍等一会rvm就安装好了
在终端输入 source ~/.bashrc
在终端输入 source ~/.bash_profile
再输入rvm -v查看安装成功

3.准备工作做完后,正式开启自动化之路

在Xcode配置证书。我这边直接让Xcode自动管理,当然,你也可以手动配置

配置证书.png



二、修改一下shell.sh 文件

根据自己项目实际,修改为自己的项目名称


6E1164EE-8EC0-4C96-BA75-6898D0992241.png

完整脚本,上传到App Store,其它可自行加上(可用)

#!/bin/bash

# 自己的AppleID账号密码
AppleID="AppleID"
AppleID_Password="AppleID密码"

project_path=$(pwd)
#取当前时间字符串添加到文件结尾
now=$(date +%Y-%m-%d-%H\:%M\:%S)
#取当前日期
today=$(date +%Y-%m-%d)

# 指定项目的scheme名称
scheme="项目的scheme名称"
# 指定项目名
project_name="项目名"
# 指定要打包的配置名
configuration="Release"
# plist文件所在目录
exportOptionsPlistPath=${project_path}/ExportOptionsForAppStore.plist
# 指定项目地址
workspace_path="${project_path}/${project_name}.xcworkspace"
# 指定输出路径
output_path="$HOME/Library/Developer/Xcode/Archives"
# 指定输出归档文件夹地址
archiveFinder_path="${output_path}/${today}"
# 指定输出归档文件地址
archive_path="${archiveFinder_path}/${project_name}${now}.xcarchive"
# 指定ipa输出地址
ipa_path="~/Desktop/Firestonelamp-IPA/${project_name}${now}"
# altool工具路径
altoolPath="/Applications/Xcode10.1.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool"

#输出设定的变量值
echo "===workspace path : ${workspace_path}==="
echo "===archive path : ${archive_path}==="
echo "===ipa path : ${ipa_path}==="
echo "===profile : ${provisioning_profile}==="

#先clean一下
echo "===开始 clean 工程==="
xcodebuild clean \
-workspace ${workspace_path} \
-scheme ${scheme} \
-configuration ${configuration} \
-quiet || exit
echo "===clean 完成==="

#根据指定的项目, scheme, configuration, 输出路径, 打出archive包
echo "===开始打包==="

if [ ! -d "${archiveFinder_path}" ]; then
    mkdir ${archiveFinder_path}
fi

xcodebuild archive \
-workspace ${workspace_path} \
-scheme ${scheme} \
-configuration ${configuration} \
-archivePath ${archive_path} \
-quiet

echo "===打包完成==="

#导出ipa包
echo "===正在导出ipa==="

xcodebuild \
-allowProvisioningUpdates \
-exportArchive \
-archivePath ${archive_path} \
-configuration ${configuration} \
-exportPath ${ipa_path} \
-exportOptionsPlist ${exportOptionsPlistPath} \
-quiet


echo "===.ipa 文件已导出==="
# open ${ipa_path}
# 验证并上传到App Store
echo "===验证并上传到App Store==="
"$altoolPath" --validate-app -f ${ipa_path}/${project_name}.ipa \
-u ${AppleID} -p ${AppleID_Password} \
-t ios --output-format xml

"$altoolPath" --upload-app -f ${ipa_path}/${project_name}.ipa \
-u  ${AppleID} -p ${AppleID_Password} \
-t ios --output-format xml
echo "===上传完成==="

exit

  • 脚本解释:

清理构建目录

echo "===开始 clean 工程==="
xcodebuild clean \
-workspace ${workspace_path} \
-scheme ${scheme} \
-configuration ${configuration} \
-quiet || exit
echo "===clean 完成==="

编译之前先clean下,就如同在Xcode进行Product -> Clean。
编译打包成Archive

xcodebuild archive \
-workspace ${workspace_path} \
-scheme ${scheme} \
-configuration ${configuration} \
-archivePath ${archive_path} \
-quiet

编译工程,编译并生成.xcarchive文件,放在build_path下,名字是project_name.xcarchive,就如在Xcode进行Product -> Archive这一步最为耗时.
将Archive导出ipa

xcodebuild \
-allowProvisioningUpdates \
-exportArchive \
-archivePath ${archive_path} \
-configuration ${configuration} \
-exportPath ${ipa_path} \
-exportOptionsPlist ${exportOptionsPlistPath} \
-quiet

将生成的.xcarchive文件导出.ipa包到指定的exportIpaPath路径下。

  • 说明:

    用\来进行换行分隔,一条shell命令过长时可以进行分割显示.
    $变量名是引用变量,拿来使用
    || exit 指明如果这一条命令执行失败,则退出当前shell.
    



  • 通过Fir-cli命令上传到Fir平台

# 将XXX替换成自己的Fir平台的token
fir login -T XXX
fir publish $exportIpaPath/$scheme_name.ipa



  • 通过altool工具提交ipa包到app store

这个工具实际上是Application Loader,打开Xcode-左上角Xcode-Open Developer Tool-Application Loader 可看到,它的路径:

# altool工具路径
altoolPath="/Applications/Xcode10.1.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool"

验证并上传到App Store # 将-u 后面的AppleID替换成自己的AppleID的账号,-p后面的AppleID_Password替换成自己的密码

echo "===验证并上传到App Store==="
"$altoolPath" --validate-app -f ${ipa_path}/${project_name}.ipa \
-u ${AppleID} -p ${AppleID_Password} \
-t ios --output-format xml

"$altoolPath" --upload-app -f ${ipa_path}/${project_name}.ipa \
-u  ${AppleID} -p ${AppleID_Password} \
-t ios --output-format xml
echo "===上传完成==="

上传到App Store的命令解释
上传到App Store的命令解释.png



exportAppstore.plist: 新建一个plist文件, 里面是一个Dictionary, key-value如下, 都是可选值, 不需要全部填上,可参考最底下链接下载参考

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, ad-hoc, package, 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.







  • 问题1:账号开启认证问题

Please sign in with an app-specific password. You can create one at appleid.apple.com

- 问题2:build号相同,在Xcode的改下项目的build版本号

  • 47FC1541-1AB7-4A93-A9D5-9F0FD1F6EA21.png

- 问题3:打包缺少证书

Error Domain=IDEProvisioningErrorDomain Code=19 "Create certificate" UserInfo={
   IDEDistributionIssueSeverity=3, 
   IDEProvisioningError_UserInfoKey_IDEProvisioningUserAction  =  <IDEProvisioningCreateTeamOwnedCertificateUserAction: 0x7fdbaa2f8490>,
   NSLocalizedRecoverySuggestion=Create a new Apple Distribution certificate for your team.,
   NSLocalizedDescription=Create certificate
}
error: exportArchive: No profiles for 'com.firestonetmt.Firestonelamp' were found

Error Domain=IDEProfileLocatorErrorDomain Code=1 "No profiles for 'com.firestonetmt.Firestonelamp' were found" UserInfo={
   IDEDistributionIssueSeverity=3,
   NSLocalizedDescription=No profiles for 'com.firestonetmt.Firestonelamp' were found, 
   NSLocalizedRecoverySuggestion = Xcode couldn't find any iOS Ad Hoc provisioning profiles matching 'com.firestonetmt.Firestonelamp'.
}

- 问题4:_error: exportArchive: "***.app" requires a provisioning profile.

error: exportArchive: "JenkinsTest.app" requires a provisioning profile.
Error Domain=IDEProvisioningErrorDomain Code=9 ""JenkinsTest.app" requires a provisioning profile."
UserInfo={
    NSLocalizedDescription="JenkinsTest.app" requires a provisioning profile., 
    NSLocalizedRecoverySuggestion=Add a profile to the "provisioningProfiles" dictionary in your Export Options property list.
}
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.
image.png



参考文章:
iOS一键搞定自动打包并发布到AppStore和Fir
iOS的打包、发布库 CLI for Building & Distributing iOS Apps (.ipa Files)



  • 扫一扫,关注我的公众号


    扫一扫,关注我.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,069评论 4 358
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,212评论 1 287
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 105,912评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,424评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,741评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,194评论 1 206
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,553评论 2 307
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,289评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,923评论 1 237
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,251评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,775评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,144评论 2 249
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,698评论 3 228
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,936评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,658评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,214评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,159评论 2 258

推荐阅读更多精彩内容