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

你可能感兴趣的:(iOS提高效率之Xcodebuild自动打包总结)