1、前言
最近在研究上传ipa文件自动上传到苹果后台(后续有时间也分享给大家啊),然后,就需要制作大量的ipa文件啊!如果手工的Archive
那不就死啦,整个步骤,大概要5分钟过程,而且不是一步到位等5分钟,所以就研究了一下项目如何自动打ipa,最后找到了 iOS项目之自动化打包 - 简书 这篇文件,然后根据需求,扩展做了全能自动化的,app-store、ad-hoc、dev 三种类型证书,另外项目如果是用cocoapod,需要用 -workspace
,否则用 -project
,都做了相当自能化的改造,下面就来看看吧!
ps: fastlane
当然能做到这些事情,但是这个工具太重,需要的配置也需要熟悉,对于刚毕业或陌生的同学有点难,学习一下ruby
也是好事~
2、使用说明
本文,也不打算讲 xcodebuild
命令的原理,大家需要自动搜索,网上很多教程了。所以,我们先过一下,怎么打包吧!
-
把
build_ipa_shell
脚本和证书配置文件夹复制到项目 -
根据要求修改项目名字和配置
-
在终端执行
sh build_ipa.sh
,不要求切换到项目的目录啊,然后选择打包的类型,然后等待就好!~ > sh /Users/HTC/Desktop/BuildIPAExample/build_ipa_shell/build_ipa.sh Place enter the number you want to export ? [ 1:app-store 2:ad-hoc 3:dev]
-
编译打包成功后,会自动打开ipa文件的目录!
3、配置说明
上面已经说了 build_ipa.sh
的配置,就是 ExportOptions-appstore.plist
/ExportOptions-dev.plist
/ ExportOptions-adhoc.plist
三个证书的配置没有说,其实也很简单,自己配置,或者让Xcode生成配置!
自己配置的就不说了,自己搜索一下教程就好,让Xcode生成,就是要 Archive
项目,然后选择 Export...
:
上面三个文件,就对应下面的三个选项:
如果选择手动,就是使用本地的证书(如果是选择自动,就是Xcode中登陆了开发者账号,自动生成和匹配证书):
等待Xcode生成ipa包,选择 Export
,Xcode就会自动生成ipa文件和证书配置文件,跟我们的脚本一样的:
最后,导出的文件中,更改ExportOptions.plist
文件名字为对应的 ExportOptions-appstore.plist
/ExportOptions-dev.plist
/ ExportOptions-adhoc.plist
,然后复制到 build_ipa_shell
脚本目录就可以啦!
4、一些坑点
打包时,遇到下面报错:
2018-09-17 10:35:23.068 xcodebuild[11322:5883826] [MT] IDEDistribution: Step failed: <IDEDistributionPackagingStep: 0x7ff88e7ab7c0>: Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value., NSFilePath=/var/folders/12/yqg0r8s508lfmzw6b91nh97m0000gn/T/ipatool-json-filepath-vo804k}
error: exportArchive: The data couldn’t be read because it isn’t in the correct format.
Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value., NSFilePath=/var/folders/12/yqg0r8s508lfmzw6b91nh97m0000gn/T/ipatool-json-filepath-vo804k}
** EXPORT FAILED **
解决方法:
将对应打包的证书plist文件的compileBitcode
内容由 true
改为 false
就可以:
<key>compileBitcode</key>
<false/>
5、源代码
具体的代码,也可参考我的Github代码:
#获取脚本执行目录
scrip_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
#工程绝对路径
project_path=$(dirname "$scrip_path")
#工程名 将XXX替换成自己的工程名
project_name=BuildIPAExample
#scheme名 将XXX替换成自己的sheme名
scheme_name=BuildIPAExample
#project_type 项目如果是用cocoapod,就改为 xcworkspace,否则用 xcodeproj
project_type=xcodeproj
#打包模式 Debug/Release
development_mode=Debug
#build文件夹路径
build_path=${project_path}/build
#plist文件所在路径
exportOptionsPlistPath=${project_path}/build_ipa_shell/ExportOptions-dev.plist
echo "Place enter the number you want to export ? [ 1:app-store 2:ad-hoc 3:dev] "
read number
while([[ $number != 1 ]] && [[ $number != 2 ]] && [[ $number != 3 ]])
do
echo "Error! Should enter 1 or 2 or 3"
echo "Place enter the number you want to export ? [ 1:app-store 2:ad-hoc 3:dev] "
read number
done
if [ $number == 1 ];then
development_mode=Release
exportOptionsPlistPath=${project_path}/build_ipa_shell/ExportOptions-appstore.plist
elif [ $number == 2 ];then
development_mode=Release
exportOptionsPlistPath=${project_path}/build_ipa_shell/ExportOptions-adhoc.plist
else
development_mode=Debug
exportOptionsPlistPath=${project_path}/build_ipa_shell/ExportOptions-dev.plist
fi
#导出.ipa文件所在路径
exportIpaPath=${project_path}/ipa_files/${development_mode}
# 生成保存ipa文件的目录
if [ ! -d ${project_path}/ipa_files ];
then
mkdir -p ${project_path}/ipa_files;
fi
# 打包类型
if [ $project_type == "xcodeproj" ];
then
project_build=project
else
project_build=workspace
fi
# 进入项目目录,方便后面的操作
cd ${project_path}
echo '///-----------'
echo '/// 正在清理工程'
echo '///-----------'
xcodebuild \
clean -configuration ${development_mode} -quiet || exit
echo '///--------'
echo '/// 清理完成'
echo '///--------'
echo ''
echo '///-----------'
echo '/// 正在编译工程:'${development_mode}
echo '///-----------'
xcodebuild \
archive -${project_build} ${project_path}/${project_name}.${project_type} \
-scheme ${scheme_name} \
-configuration ${development_mode} \
-archivePath ${build_path}/${project_name}.xcarchive -quiet || exit
echo '///--------'
echo '/// 编译完成'
echo '///--------'
echo ''
echo '///----------'
echo '/// 开始ipa打包'
echo '///----------'
xcodebuild -exportArchive -archivePath ${build_path}/${project_name}.xcarchive \
-configuration ${development_mode} \
-exportPath ${exportIpaPath} \
-exportOptionsPlist ${exportOptionsPlistPath} \
-quiet || exit
if [ -e $exportIpaPath/$scheme_name.ipa ]; then
echo '///----------'
echo '/// ipa包已导出'
echo '///----------'
open $exportIpaPath
else
echo '///-------------'
echo '/// ipa包导出失败 '
echo '///-------------'
fi
echo '///------------'
echo '/// 打包ipa完成 '
echo '///-----------='
echo ''
# 打开生成ipa的目录
open ${exportIpaPath}
# echo '///-------------'
# echo '/// 开始发布ipa包 '
# echo '///-------------'
# if [ $number == 1 ];then
# #验证并上传到App Store
# # 将-u 后面的XXX替换成自己的AppleID的账号,-p后面的XXX替换成自己的密码
# altoolPath="/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool"
# "$altoolPath" --validate-app -f ${exportIpaPath}/${scheme_name}.ipa -u XXX -p XXX -t ios --output-format xml
# "$altoolPath" --upload-app -f ${exportIpaPath}/${scheme_name}.ipa -u XXX -p XXX -t ios --output-format xml
# else
# #上传到Fir
# # 将XXX替换成自己的Fir平台的token
# fir login -T XXX
# fir publish $exportIpaPath/$scheme_name.ipa
# fi
exit 0
6、总结
通过本次脚本,又让效率提升了n倍,以后打包不在害怕啦!!!另外,脚本中,还包含 上传到 AppStore
或第三方平台的功能,这里就先不写啦,大家有兴趣可以自行实践,和前面几篇技巧一样,大家应该能感受到shell脚本编程的魅力,希望大家能举一反三,授鱼不如授渔!生活工作中结合 sehll 脚本,提高效率和自动化,珍爱时间不是梦!
后续有更多技巧,会继续给大家分享,期待~
参考
- iOS项目之自动化打包 - 简书
- Xcode9 iOS export archive fails on correct format |Apple Developer Forums
- iHTCboy/iShell: Shell脚本编程技巧,总结一些常用的提高效率的方法。
- iHTCboy/BuildIPAExample: Build IPA file Example
- 如有疑问,欢迎在评论区一起讨论!
- 如有不正确的地方,欢迎指导!
注:本文首发于 iHTCboy's blog,如若转载,请注来源