美文网首页
iOS项目自动打包并上传至FTP服务器 Shell脚本

iOS项目自动打包并上传至FTP服务器 Shell脚本

作者: ElegantLiar | 来源:发表于2017-12-04 14:43 被阅读108次

    简介

    公司自己搭建FTP服务器用于测试人员、公司员工安装IPA包,为简化开发人员工作量,将整个打包、上传流程简化为脚本操作。配置好相关信息后,打开APP,点击生成脚本,粘贴执行生成的脚本即可完成。

    工具图标.png 工具截图.png

    使用方法

    1. 拷贝Shell文件夹至.xcodeproj同级文件夹,移动 自动打包工具 至.xcodeproj上级目录


      文件放置相对目录.png
    2. 配置Shell文件夹下的各个Plist文件,添加provisioningProfiles下的key-value,key为对应target的bundle id,value为对应模式下provisioningProfile文件名字,如有多个target,需要添加多个键值对


      plist文件配置.png
    3. 确保plist中用到的所有配置文件存在于~/Library/MobileDevice/Provisioning Profiles路径下,如没有在对应文件夹下,在开发者后台下载并移动至上述目录


      配置文件存放位置.png
    4. 修改Shell文件夹下的build.sh脚本文件,修改的参数如下图所示


      脚本文件修改参数1.png 脚本文件修改参数2.png 脚本文件修改参数3.png
    5. 找到自动打包工具,右键显示包内容,修改Contents->Resources->build.sh文件内的projectFolderName参数为.xcodeproj所在的文件夹名称

    自动打包工具包内容.png
    1. 脚本运行完毕之后,会在scheme_name-IPA文件夹下生成对应的log文件、IPA文件、xcarchive文件等,如果不需要提交到git,可自行删除。


      IPA文件夹文件列表.png

    以上操作只需要配置一次,接下来

    运行 自动打包工具 -> 选择模式 -> 点击生成按钮 -> control + v -> 回车 等待整个流程的进行,整个过程的LOG可以在终端观察。


    终端截图1.png
    终端成功截图2.png

    流程解析

    1. 主要操作是由Shell文件夹下的build.sh完成的,整个脚本又分为两个部分,打包和上传,打包过程由Pod-Clean-Build-Archive-Export几个步骤构成,之后将IPA包上传至FTP服务器
    2. 自动打包工具的作用是生成一段执行脚本的代码(如sh build.sh debug 1),用户也可直接在Shell下使用上面产生的命令操作,这样做方便一些不了解脚本的用户使用。没有设置成一键打包上传的原因在于,这种可以方便用户在终端查看LOG信息。
    3. 文件的放置位置很关键,整个脚本的运行基于文件所在目录进行操作。

    Shell脚本分析

    SECONDS=0
    # 是否编译工作空间 (例:若是用Cocopods管理的.xcworkspace项目,赋值true; 用Xcode默认创建的.xcodeproj, 赋值false)
    is_workspace="true"
    # 指定项目的scheme名称
    scheme_name="DEMO"
    # 设置导出IPA包的名称 如DEMO导出包名为DEMO.ipa
    export_iap_name="DEMO"
    # 工程中Target对应的配置plist文件名称, Xcode默认的配置文件为Info.plist
    info_plist_name="Info"
    # 指定要打包编译的方式 : Release,Debug...$1
    build_configuration=$1
    
    echo "\n\033[32;1m************************* 您选择了 $build_configuration 模式 ************************* \033[0m\n"
    
    # 导出ipa所需要的plist文件路径 (默认为AdHocExportOptionsPlist.plist)
    ExportOptionsPlistPath="./shell/AdHocExportOptionsPlist.plist"
    # 返回上一级目录,进入项目工程目录
    cd ..
    # 获取项目名称
    project_name=`find . -name *.xcodeproj | awk -F "[/.]" '{print $(NF-1)}'`
    # 获取版本号,内部版本号,bundleID
    info_plist_path="$project_name/$info_plist_name.plist"
    bundle_version=`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" $info_plist_path`
    bundle_build_version=`/usr/libexec/PlistBuddy -c "Print CFBundleIdentifier" $info_plist_path`
    bundle_identifier=`/usr/libexec/PlistBuddy -c "Print CFBundleVersion" $info_plist_path`
    
    # 强制删除旧的文件夹
    rm -rf ./$scheme_name-IPA
    # 指定输出ipa路径
    export_path=./$scheme_name-IPA
    # 指定输出归档文件地址
    export_archive_path="$export_path/$scheme_name.xcarchive"
    # 指定输出ipa地址
    export_ipa_path="$export_path"
    # 指定输出ipa名称 : scheme_name + bundle_version
    suffix=`date +"%m%d%H%M"`
    ipa_name="$scheme_name-v$bundle_version_$suffix"
    version="$bundle_version.$suffix"
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $version" "$info_plist_path"
    # certifcate
    CODE_SIGN_DISTRIBUTION="iPhone Distribution: USERNAME (Q2J5575DBC)"
    CODE_SIGN_DEVELOPMENT="iPhone Developer: USERNAME (YXP3A9ACE8)"
    

    以上代码主要为配置项目的基础参数

    method = $2
    if test -n "$method"
    then
    if test "$method" = "1" ; then
    ExportOptionsPlistPath="./shell/AdHocExportOptionsPlist.plist"
    elif [ "$method" = "2" ]; then
    ExportOptionsPlistPath="./shell/AppStoreExportOptionsPlist.plist"
    elif [ "$method" = "3" ]; then
    ExportOptionsPlistPath="./shell/EnterpriseExportOptionsPlist.plist"
    elif [ "$method" = "4" ]; then
    ExportOptionsPlistPath="./shell/DevelopmentExportOptionsPlist.plist"
    else
    echo "\n\033[31;1m************************* 您输入的参数无效!!! *************************\033[0m\n"
    exit 1
    fi
    else
    UPLOADFIR=false
    fi
    
    
    echo "\033[32m************************* 开始构建项目 ************************* \033[0m\n"
    # 指定输出文件目录不存在则创建
    if test -d "$export_path" ; then
    echo $export_path
    else
    mkdir -pv $export_path
    fi
    
    if $is_workspace ; then
    echo "\n\033[32m************************* 开始pod ************************* \033[0m"
    pod install --verbose --no-repo-update
    echo "\033[32m************************* pod完成 ************************* \033[0m\n"
    

    以上代码为根据外部传入的参数,获取输出打包的类型,ad-hoc/appStore/企业证书等 -> 创建Archive包的输出路径,UPLOADFIR等参数在上传FTP服务器中使用不到,可忽略 -> POD项目

    if test $build_configuration="Debug" ; then
    echo "\n\033[32;1m************************* 您选择了以 xcworkspace-Debug 模式打包 *************************\033[0m"
    # step 1. Clean
    xcodebuild clean -workspace $project_name.xcworkspace -scheme $scheme_name -configuration $build_configuration -alltargets
    # step 2. Build
    xcodebuild -workspace $project_name.xcworkspace -scheme $scheme_name -sdk iphoneos -configuration $build_configuration -CODE_SIGN_IDENTITY=$CODE_SIGN_DEVELOPMENT
    # step 3. Archive
    xcodebuild archive -workspace $project_name.xcworkspace -scheme $scheme_name -configuration $build_configuration -archivePath $export_archive_path
    elif [ $build_configuration="Release" ]; then
    echo "\n\033[32;1m************************* 您选择了以 xcworkspace-Release 模式打包 *************************\033[0m"
    # step 1. Clean
    xcodebuild clean -workspace $project_name.xcworkspace -scheme $scheme_name -configuration $build_configuration -alltargets
    # step 2. Build
    xcodebuild -workspace $project_name.xcworkspace -scheme $scheme_name -sdk iphoneos -configuration $build_configuration -CODE_SIGN_IDENTITY=$CODE_SIGN_DISTRIBUTION
    # step 3. Archive
    xcodebuild archive -workspace $project_name.xcworkspace -scheme $scheme_name -configuration $build_configuration -archivePath $export_archive_path
    else
    echo "\n\033[31;1m************************* 您定义的打包方式的不正确 😢 😢 😢 *************************\033[0m\n"
    echo "Usage:\n"
    echo "sh build.sh Debug"
    echo "sh build.sh Release"
    exit 1
    fi
    else
    if test $build_configuration="Debug" ; then
    echo "\n\033[32;1m************************* 您选择了以 xcodeproj-Debug 模式打包 *************************\033[0m"
    # step 1. Clean
    xcodebuild clean -project $project_name.xcodeproj -scheme $scheme_name -configuration $build_configuration -alltargets
    # step 2. Build
    xcodebuild -project $project_name.xcodeproj -scheme $scheme_name -sdk iphoneos -configuration $build_configuration -CODE_SIGN_IDENTITY=$CODE_SIGN_DEVELOPMENT
    # step 3. Archive
    xcodebuild archive -project $project_name.xcodeproj -scheme $scheme_name -configuration $build_configuration -archivePath $export_archive_path
    elif [ $build_configuration="Release" ]; then
    echo "\n\033[32;1m************************* 您选择了以 xcodeproj-Release 模式打包 *************************\033[0m"
    # step 1. Clean
    xcodebuild clean -project $project_name.xcodeproj -scheme $scheme_name -configuration $build_configuration -alltargets
    # step 2. Build
    xcodebuild -project $project_name.xcodeproj -scheme $scheme_name -sdk iphoneos -configuration $build_configuration -CODE_SIGN_IDENTITY=$CODE_SIGN_DISTRIBUTION
    # step 3. Archive
    xcodebuild archive -project $project_name.xcodeproj -scheme $scheme_name -configuration $build_configuration -archivePath $export_archive_path
    else
    echo "\n\033[31;1m************************* 您定义的打包方式的不正确 😢 😢 😢 *************************\033[0m\n"
    echo "Usage:\n"
    echo "sh build.sh Debug"
    echo "sh build.sh Release"
    exit 1
    fi
    fi
    
    # 检查是否构建成功
    # xcarchive 实际是一个文件夹不是一个文件所以使用 -d 判断
    if test -d "$export_archive_path" ; then
    echo "\n\033[32;1m************************* 项目构建成功 🚀 🚀 🚀 *************************\033[0m\n"
    else
    echo "\n\033[31;1m************************* 项目构建失败 😢 😢 😢 *************************\033[0m\n"
    exit 1
    fi
    
    echo "\033[32m************************* 开始导出ipa文件 ************************* \033[0m"
    xcodebuild -exportArchive -archivePath $export_archive_path -exportPath $export_ipa_path -exportOptionsPlist $ExportOptionsPlistPath
    # 修改ipa文件名称
    mv $export_ipa_path/$scheme_name.ipa $export_ipa_path/$export_iap_name.ipa
    
    # 检查文件是否存在
    if test -f "$export_ipa_path/$export_iap_name.ipa" ; then
    echo "\n\033[32;1m************************* 导出 $ipa_name.ipa 包成功 🎉 🎉 🎉 *************************\033[0m\n"
    fi
    

    以上代码为根据外部传入Debug/Release参数配置打包类型,然后进行项目的clean、build、archive、exportIPA包等操作

    #SFTP配置信息
    #用户名
    USER="XXXXX"
    #密码
    PASSWORD="XXXXX"
    #待上传文件根目录
    SRCDIR="$export_ipa_path/$export_iap_name.ipa"
    #IP
    IP=133.33.33.33
    #端口
    PORT=21
    
    #修改folderName为上传的FTP目录
    curl -u $USER:$PASSWORD -T $SRCDIR ftp://$IP/FOLDERNAME/FOLDERNAME/
    
    exit 0
    

    以上代码为上传导出的IPA包至FTP服务器的具体目录下

    遇到的问题

    • 打包的时候产生错误,因为plist中用到的所有配置文件未存在于~/Library/MobileDevice/Provisioning Profiles路径下
    • 自动打包工具放置位置错误会导致调用脚本文件失败
    • 起初上传脚本使用的为ftp命令,但是在最新版的MAC系统此命令被禁用,后修改为crul命令

    工具以及相关文件GitHub地址

    脚本文件中有一些不必要的参数和语句可自行删除,打包工具目前根据公司项目只配置了ad-hoc和Appstore,如果需要企业证书,可自己使用脚本命令运行build.sh进行操作。

    因为涉及一些公司相关文件,所以很多图片相关信息都进行了打码处理,有不懂的可以私聊或者评论文章,我会在看到后第一时间回复。

    相关文章

      网友评论

          本文标题:iOS项目自动打包并上传至FTP服务器 Shell脚本

          本文链接:https://www.haomeiwen.com/subject/iacxixtx.html