iOS提高效率之Xcodebuild自动打包总结

一、说明

最近,给小伙伴们做了一个,有关 xcodebuild 自动打包的技术分享,在整理脚本的过程中,遇到了一些问题,并把问题做了一下整理,希望给遇到相同问题的小伙伴做一个参考

二、完整的shell脚本
1.xcodebuild 生成IPA 包,并上传到蒲公英、fir.im、AppStore 的shell脚本代码
#!/bin/sh

#  WallPaperScript.sh

#计时
SECONDS=0

#取当前时间字符串添加到文件结尾
now=$(date +"%Y%m%d-%H:%M")

# 获取 setting.plist 文件路径
setting_path=./setting.plist

# 项目名称
project_name=$(/usr/libexec/PlistBuddy -c "print project_name" ${setting_path})

# 项目路径
project_path=$(/usr/libexec/PlistBuddy -c "print project_path" ${setting_path})

# workspace/xcodeproj 路径(根据项目是否使用cocoapod,确定打包的方式)
if [ -d "./${project_name}.xcworkspace" ];then # 项目中存在workspace
workspace_path="${project_path}/${project_name}.xcworkspace"
else # 项目中不存在 workspace
workspace_path="${project_path}/${project_name}.xcodeproj"
fi

# scheme名称
scheme_name=$(/usr/libexec/PlistBuddy -c "print scheme_name" ${setting_path})

# 项目版本
project_version=$(/usr/libexec/PlistBuddy -c "print project_version" ${setting_path})

# 开发者账号
dev_account=$(/usr/libexec/PlistBuddy -c "print dev_account" ${setting_path})

# 开发者密码
dev_password=$(/usr/libexec/PlistBuddy -c "print dev_password" ${setting_path})

# 配置打包方式:Release/ad-hoc/Debug
configuration=$(/usr/libexec/PlistBuddy -c "print configuration" ${setting_path})

# 发布地址:蒲公英->PGY,苹果->APPStore, fir.im->FI
upload_address=$(/usr/libexec/PlistBuddy -c "print upload_address" ${setting_path})

# ipa包名称:项目名+版本号+打包类型
ipa_name=$(/usr/libexec/PlistBuddy -c "print ipa_name" ${setting_path})

# ipa包路径
ipa_path2=$(/usr/libexec/PlistBuddy -c "print ipa_path" ${setting_path})/${now}
ipa_path="${ipa_path2}-V${project_version}-${upload_address}"

# 打包配置plist文件路径 (初始化)
plist_path=$(/usr/libexec/PlistBuddy -c "print plist_path" ${setting_path})

# 编译build路径
archive_path="${ipa_path}/${project_name}.xcarchive"

# 上传到蒲公英设置
user_key=$(/usr/libexec/PlistBuddy -c "print user_key" ${setting_path})
api_key=$(/usr/libexec/PlistBuddy -c "print api_key" ${setting_path})
password=$(/usr/libexec/PlistBuddy -c "print password" ${setting_path})

# 上传fir.im 设置
fir_token=$(/usr/libexec/PlistBuddy -c "print fir_token" ${setting_path})

#打包方式配置
if [ ${upload_address} == "APPStore" ];then # 发布到 AppStore 配置 Release
    configuration="Release"
    plist_path=${project_path}/exportAppstore.plist
elif [ ${upload_address} == "PGY" ] ||[ ${upload_address} == "FI" ];then # 发布到第三方平台可 配置 Release、Debug
    if [ ${configuration} == "Release" ];then
     plist_path=${project_path}/exportAdHoc.plist
    else
     plist_path=${project_path}/exportDevelopment.plist
    fi
else # 只打包,不发布到任何平台
    if [ ${configuration} == "Release" ];then
       plist_path=${project_path}/exportAppstore.plist
    else
       plist_path=${project_path}/exportDevelopment.plist
    fi
fi

echo '=============正在清理工程============='
xcodebuild clean -configuration ${configuration} -quiet || exit

echo '清理完成-->>>--正在编译工程:'${configuration}

# 通过workspace方式打包
if [ -d "./${project_name}.xcworkspace" ];then # 项目中存在workspace
    xcodebuild archive -workspace ${workspace_path} -scheme ${scheme_name} \
    -configuration ${configuration} \
    -archivePath ${archive_path} -quiet || exit
else #通过xcodeproj 方式打包
    xcodebuild archive -project ${workspace_path} -scheme ${scheme_name} \
    -configuration ${configuration} \
    -archivePath ${archive_path} -quiet || exit
fi

# 检查是否构建成功(build)
if [ -d "$archive_path" ] ; then
    echo '=============项目构建成功============='
else
    echo '=============项目构建失败============='
    exit 1
fi

echo '编译完成-->>>--开始ipa打包'
xcodebuild -exportArchive -archivePath ${archive_path} \
-configuration ${configuration} \
-exportPath ${ipa_path} \
-exportOptionsPlist ${plist_path} \
-quiet || exit

if [ -e ${ipa_path}/${ipa_name}.ipa ]; then
    echo '=============ipa包导出成功============'
    open $ipa_path
else
    echo '=============ipa包导出失败============'
fi

echo '打包ipa完成-->>>--开始发布ipa包'

if [ ${upload_address} == "APPStore" ];then # 发布到APPStore
    echo '发布ipa包到 =============APPStore============='
    altoolPath="/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool"
    "$altoolPath" --validate-app -f ${ipa_path}/${ipa_name}.ipa -u ${dev_account} -p ${dev_password} -t ios --output-format xml
    "$altoolPath" --upload-app -f ${ipa_path}/${ipa_name}.ipa -u ${dev_account} -p ${dev_password} -t ios --output-format xml

    if [ $? = 0 ];then
    echo "=============提交AppStore成功 ============="
    else
    echo "=============提交AppStore失败 ============="
    fi

elif [ ${upload_address} == "PGY" ];then # 发布到蒲公英平台
    echo '发布ipa包到 =============蒲公英平台============='
    curl -F "file=@${ipa_path}/${ipa_name}.ipa" -F "uKey=${user_key}" -F "_api_key=${api_key}" -F "password=${password}" https://www.pgyer.com/apiv1/app/upload

    if [ $? = 0 ];then
    echo "=============提交蒲公英成功 ============="
    else
    echo "=============提交蒲公英失败 ============="
    fi

elif [ ${upload_address} == "FI" ];then # 发布到fir.im 平台
    echo '发布ipa包到 =============fir.im平台============'
    # 需要先在本地安装 fir 插件,安装fir插件命令: gem install fir-cli
    fir login -T ${fir_token}              # fir.im token
    fir publish  ${ipa_path}/${ipa_name}.ipa

    if [ $? = 0 ];then
    echo "=============提交fir.im成功 ============="
    else
    echo "=============提交fir.im失败 ============="
    fi
else # 未配置发布地址
    echo "=============未发布 ipa包(打包方式:$configuration) 到任何平台============="
fi

# 输出总用时
echo "执行耗时: ${SECONDS}秒"
exit 0

2.需要的plist 配置文件信息

(1)下面是setting.plist 配置文件信息
project_name:项目的名字
project_path:项目路径
project_version:项目的版本号
scheme_name:scheme
ipa_name:要生成的IPA的名字
ipa_path:生成IPA 文件路径
plist_path:配置文件信息路径
configuration:打包方式(这里只配置了 Release、Debug,把IPA包上传到AppStore配置为Release,上传到蒲公英、fir.im配置为 Release 或者 Debug 都可以)
upload_address:上传地址(AppStore/PGY(蒲公英)/FI(fir.im)/None(也可以不填写),只生成IPA包,不发布到任何平台)
user_key:蒲公英 user_key
api_key: 蒲公英 api_key
password:蒲公英下载安装包时需要的密码(选填或者传空字符串)
fir_token:fir.im token (先把fir插件安装到本地,才可以使用此命令)
dev_account:苹果开发者账号
dev_password:苹果开发者密码


011.png

(2)下面是exportAppStore.plist 配置文件信息
com.dating.luowallpaper(bundleId):对应的发布 配置概要文件
method:app-store
uploadBitcode:配置是否上传 bitcode ,xcode配置默认 YES
uploadSymbols:是否上传 dSYMs
teamID:发布证书 的 teamID , 即 App ID Prefix

012.png

(3) 下面是exportAdHoc.plist 配置文件信息
com.dating.luowallpaper(bundleId):对应的 Ad-Hoc 配置概要文件


013.png

(4) 下面是exportDevelopment.plist 配置文件信息
com.dating.luowallpaper(bundleId):对应的 development 配置概要文件
teamID: 发布证书 的 teamID ,即 App ID Prefix(注意不要写成,开发证书对应的teamID)


014.png
三、执行脚本文件之前需要注意的事项

1、shell脚本文件、setting.plist、exportAppStore.plist、exportAdHoc.plist 、exportDevelopment.plist 这五个文件要放到项目根目录下

2、选择手动配置 provisioning profiles 文件,根据打包的方式不同,在xcode中配置不同的 配置概要文件(AppStore / AdHoc /development ),不要选择自动配置,否则会打包失败 ,请看下图

015.png

016.png

3、为了保证我们每次打的IPA包都是唯一的,需要对Xcode进行设置,保证我们每次archive的时候,build 自动加 1 ,具体的设置可以参考下面的 网址:https://www.cnblogs.com/wengzilin/p/4648177.html?utm_source=tuicool&utm_medium=referral

4.为了保证 fir 命令正常执行,先在本地安装 fir 插件,安装fir插件命令: gem install fir-cli

四、执行脚本

打开终端,cd 到项目的根目录,然后执行 ./xxx.sh 脚本,如果配置信息没问题,就会自动在配置好的 setting.plist 的ipa_path 路径下生成 一个文件夹,里面包含5个文件(DistributionSummary.plist、ExportOptions.plist、Packaging.log、xxx.ipa、xxx.xcarchive),执行完脚本会自动打开文件夹,根据配置好的信息,把IPA包发布到对应的平台

五、总结

这是自己最近给小伙伴做的一次基于xcodebuild自动打包技术的分享,希望各位小伙伴可以用的到,如果有什么疑问欢迎大家一起讨论,共同学习进步~

追加

最近用xcode 9.4 版本测试了一下自动打包时的证书配置,在TARGETS配置选项选择 Automatically manage signing 时,也可以正常打 debug 和 release 的 IPA安装包。前提是要 把 Development 和 Distribution 对应的 Provisioning Profiles 文件安装到本地 ,即使选择自动配置证书,但是使用脚本打包的时候依然需要 Provisioning Profiles 文件,如果本地没有Provisioning Profiles 文件,在导出 IPA 包的时候会提示,缺少对应的 rovisioning Profiles 文件的错误,最终,会导致导出 IPA 包失败。

demo

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

推荐阅读更多精彩内容