打包流程:
编译.xcarchive包;
生成.ipa文件;
上传到苹果商店或第三方平台。
自动化: 这里所说的自动化,主要是通过shell脚本,利用 Command Line Tools 提供的 xcodebuild
命令来编译和导出 ipa,再通过 Application Loader 提供的 altool
命令行工具,或者其他三方平台提供的命令行工具上传 ipa 和 dSYM 文件。
清理构建目录 编译前先clean,相当于在 Xcode 进行 Product -> clean。
1 2 xcodebuild \ clean -configuration ${development_mode}
-configuration
用来表示打包的方式,相当于打包前配置 Edit scheme -> info -> Build configuration,告诉编译器打出来的包是何种包,比如 Release、InHouse等。
编译xcarchive包 1 2 3 4 5 xcodebuild archive \ -workspace ${project_path} /${project_name} .xcworkspace \ -scheme ${scheme_name} \ -configuration ${development_mode} \ -archive Path ${build_path} /${project_name} .xcarchive
-workspace
表示工作空间,一个项目中有多个project
时,比如通过 pod 集成了三方库后都会自动创建一个新的工作空间。如果没有,可以不加这个参数。-archivePath
,用来配置生成的.xcarchive的路径。
导出ipa文件 1 2 3 4 xcodebuild -exportArchive -archive Path ${build_path} /${project_name} .xcarchive \ -configuration ${development_mode} \ -exportPath ${exportIpaPath} \ -exportOptionsPlist ${exportOptionsPlistPath}
-exportPath
表示 ipa 文件的输出路径;
-exportOptionsPlist
表示 ExportOptions.plist 配置文件的路径。此 plist 是打包时必须的文件,在手动打包并 export 出 ipa 包时,可以在 ipa 包的同级目录下找到,可以拿过来用,或者通过 Xcode 手动创建一份。如果有多个渠道包,也可以通过脚本生成对应的 plist。
#示例:ExportOptions.plist
1 2 3 4 5 6 7 8 9 10 11 12 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd" > <plist version ="1.0" > <dict > <key > teamID</key > <string > 略略略</string > <key > method</key > <string > enterprise</string > <key > uploadSymbols</key > <true /> </dict > </plist >
注意:Xcode9 之后,ExportOptions.plist 需要指定的信息有变,具体可以参考 这里 ~
#完整示例
下面是完整的 shell 脚本,实现了编译.xcarchive、导出 ipa 与 dSYM,命名为autobuild.sh
,放在工程根目录下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 #!/bin/sh echo ">>>>>>>>>>>> Start at $(date) <<<<<<<<<<<<<<<" PROJECT_ROOT_PATH=$PWD AUTOBUILD_PATH="$PROJECT_ROOT_PATH /AutoBuild" CURRENT_DATE=$(date +%Y_%m%d_%H%M) WORKSPACE_NAME="Demo.xcworkspace" HEADER_PLIST="$AUTOBUILD_PATH /Header.plist" EXPORT_PLIST="$AUTOBUILD_PATH /ExportOptions.plist" KEY_SCHEME="KEY_SCHEME" KEY_APP_NAME="KEY_APP_NAME" KEY_TEAM_ID="KEY_TEAM_ID" KEY_DEV_ID="KEY_DEV_ID" DemoInHouse={$KEY_SCHEME :"DemoInHouse" ,$KEY_APP_NAME :"InHouse" ,$KEY_TEAM_ID :"xxxxxxxxxx" ,$KEY_DEV_ID :"xxx" } DemoRelease={$KEY_SCHEME :"DemoRelease" ,$KEY_APP_NAME :"Release" ,$KEY_TEAM_ID :"xxxxxxxxxx" ,$KEY_DEV_ID :"xxx" } FLAVORS=($DemoInHouse )parse_json (){echo $1 | sed 's/.*' $2 ':\([^,}]*\).*/\1/' } BUILD_DIR="$PROJECT_ROOT_PATH /Build" RELEASE_DIR="$BUILD_DIR /Products" rm -rdf $BUILD_DIR OUT_BINARY_DIR="$PROJECT_ROOT_PATH /binarys_$CURRENT_DATE " if [ ! -d $OUT_BINARY_DIR ]; then mkdir $OUT_BINARY_DIR fi for ((i = 0; i < ${#FLAVORS[@]} ; i++))do TARGET_SCHEMES=$(parse_json ${FLAVORS[$i]} $KEY_SCHEME ) TARGET_APP_NAMES=$(parse_json ${FLAVORS[$i]} $KEY_APP_NAME ) TARGET_TEAM_IDS=$(parse_json ${FLAVORS[$i]} $KEY_TEAM_ID ) TARGET_DEV_IDS=$(parse_json ${FLAVORS[$i]} $KEY_DEV_ID ) rm $EXPORT_PLIST cat $HEADER_PLIST >> $EXPORT_PLIST echo "<plist version=\"1.0\">" >> $EXPORT_PLIST echo "<dict>" >> $EXPORT_PLIST echo "<key>teamID</key>" >> $EXPORT_PLIST echo "<string>$TARGET_TEAM_IDS </string>" >> $EXPORT_PLIST echo "<key>method</key>" >> $EXPORT_PLIST echo ">>>>>>>>>>>>>>>>>>>>>>>> target scheme $TARGET_SCHEMES " if [ $TARGET_SCHEMES = "DemoInHouse" ]; then echo "<string>enterprise</string>" >> $EXPORT_PLIST echo ">>>>>>>>>>>>>>>>>>>>>>>> enterprise Done" else echo "<string>app-store</string>" >> $EXPORT_PLIST echo ">>>>>>>>>>>>>>>>>>>>>>>> app-store Done" fi echo "<key>uploadSymbols</key>" >> $EXPORT_PLIST echo "<true/>" >> $EXPORT_PLIST echo "</dict>" >> $EXPORT_PLIST echo "</plist>" >> $EXPORT_PLIST echo ">>>>>>>>>>>>>>>>>>>>>>>> Reset export options Done" cd $AUTOBUILD_PATH ./replace_res.sh $TARGET_SCHEMES cd $PROJECT_ROOT_PATH echo ">>>>>>>>>>>>>>>>>>>>>>>> Reset res Done" ARCHIVE_FILE="$OUT_BINARY_DIR /$TARGET_APP_NAMES .xcarchive" DSYMS_FILE="$TARGET_APP_NAMES .dSYMs.zip" xcodebuild -workspace $WORKSPACE_NAME -scheme $TARGET_SCHEMES -configuration $TARGET_APP_NAMES clean xcodebuild archive -workspace $WORKSPACE_NAME -scheme $TARGET_SCHEMES -configuration $TARGET_APP_NAMES -archivePath $ARCHIVE_FILE cd $ARCHIVE_FILE zip -r $DSYMS_FILE "dSYMs" mv $DSYMS_FILE $OUT_BINARY_DIR cd $PROJECT_ROOT_PATH xcodebuild -exportArchive -archivePath $ARCHIVE_FILE -exportPath $OUT_BINARY_DIR -exportOptionsPlist $EXPORT_PLIST echo "apple id paired" >> "$OUT_BINARY_DIR /$TARGET_APP_NAMES_$TARGET_DEV_IDS " echo ">>>>>>>>>>>>>>>>>>>>>>>> $TARGET_SCHEMES single loop Done" done echo ">>>>>>>>>>>> Finish at $(date) <<<<<<<<<<<<<<<"
使用时先根据需要打包的版本,修改FLAVORS=($DemoInHouse)
中的内容。如果只打一个包,更换$后的命名即可;如果需要打多个包,则在输入多个包名,以逗号隔开,如:FLAVORS=($DemoInHouse,$DemoRelease)
。最后,在终端中./autobuild.sh
,直接执行脚本即可。
验证并上传到商店 Xcode 集成了 Application Loader,你可以用它来手动上传 App 的二进制文件。这里继续使用脚本的方式,通过 Application Loader 的命令行工具 altool 来验证二进制文件并上传到商店。
1 2 3 4 5 6 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 appleID -p password -t ios --output-format xml"$altoolPath" --upload-app -f ${exportIpaPath}/${scheme_name}.ipa -u appleID -p password -t ios --output-format xml
参数
详细说明
–validate-app
您要验证指定的 App。
–upload-app
您要上传指定的 App。
-f file
正在验证或上传的 App 的路径和文件名。
-u username
您的用户名。
-p password
您的用户密码。
–output-format [xml or normal]
您想让 Application Loader 以结构化的 XML 格式还是非结构化的文本格式返回输出信息。默认情况下,Application Loader 以文本格式返回输出信息。
上传到Fir 1 2 firApiToken ="xxxxxxxxxxx" fir publish $exportIpaPath /$scheme_name .ipa -T "$firApiToken "
注意:使用脚本上传到Fir平台前,需要先安装 fir-cli:
上传到蒲公英 1 curl -F "file=@$exportIpaPath /$scheme_name .ipa" -F "uKey=xxx" -F "_api_key=xxx https://qiniu-storage.pgyer.com/apiv1/app/upload
请根据开发者自己的账号,将其中的 uKey 和 _api_key 的值替换为相应的值。完整的使用规则请看 这里 ~
上传符号表 如果应用接入了崩溃分析工具,会要求将dSYM文件上传到对应平台的后台中,比如接入bugly时,可以通过以下脚本上传符号表文件:
1 java -jar buglySymboliOS.jar -d -i $dSYM -u -id "xx" -key "xx" -package "com.xx.xx" -version "$version " -o "xx.zip"
bugly 上传 dSYM 文件需要事先下载一个工具包,具体的配置和使用方法可以参考 这里 ~
其他工具 当然,还有一些更专业化的自动化部署和发布工具,如:
这些工具极大地简化了我们手动发布时的一些枯燥、重复的工作,比如截图、代码签名以及发布。这里就不一一介绍了,可以自行到其官网查询~
相关参考:
#©JiaJung-自动打包发布到Fir和AppStore
#©zackzheng-详解Shell脚本实现iOS自动化编译打包提交
#©Github.webfrogs-xcode_shell
#©FastLane-自动化打包发布
#©Application Loader-altool工具
#©树叶有砖攻-Xcode9 xcodebuild export plist 配置