变更记录
方案名称 打包 - 使用 Xcodebuild 进行命令行打包
关键字 打包 \ 工具 \ Xcodebuild \ 命令行打包 \ 自动化打包 \ 自动编译打包脚本
需求场景
为实现打包脚本做准备,简化打包流程
参考链接
使用 Xcodebuild + Jenkins + Apache 做 iOS 持续集成
动手搭建 iOS CI 环境之「了解 xcodebuild 命令」
使用 xcodebuild 从 archive 导出 ipa (推荐)
GitHub - spritefly/ios-builder
简书 - 敲一下enter键,完成iOS的打包工作
简书 - iOS 自动构建命令——xcodebuild
CSDN - iOS编译过程的原理和应用 (推荐)
详细内容 以工程名为 TestBuildProject.xcodeproj 的工程举例如下
首先,打开终端,进入工程文件 TestBuildProject.xcodeproj 所在同级目录
$ cd yourPathTo/TestBuildProject
然后,使用 Xcodebuild 进行命令行打包,主要分为三个步骤
1. clean 工程
$ xcodebuild clean -project pathtoyour/TestBuildProject.xcodeproj -alltargets
命令解释:该行命令是对工程下全部 targets 进行 clean 操作
2. 生成 .xcarchive 文件,该文件包含用于解析 crash 日志的 .dSYM 文件和工程编译完成的 .app 文件
$ xcodebuild -project pathtoyour/TestBuildProject.xcodeproj -archivePath ‘~/Desktop/TestBuildProject.xcarchive’ -sdk iphoneos -destination ‘generic/platform=iOS’ -scheme “TestBuildProject” -configuration ‘Release’ archive
命令解释:该行命令是将当前目录下的 TestBuildProject.xcodeproj 工程编译生成 estBuildProject.xcarchive 文件并输出到桌面,生成参数包括 -sdk 为 iphoneos , -configuration 为 Release
注意:
若包含 xcworkspace 文件,务必添加 -workspace TestBuildProject.xcworkspace 参数
执行命令前务必确认打包证书与相关 Provisioning Profile 文件配置正确
3. 生成 .ipa 文件,该文件用于直接上传 AppStore 或者直接安装
$ xcodebuild -exportArchive -exportFormat IPA -archivePath ‘/Desktop/TestBuildProject.xcarchive’ -exportPath ‘/Desktop/TestBuildProject.ipa’ -exportProvisioningProfile ‘DistributionAll’
命令解释:该行命令是将桌面上的 TestBuildProject.xcarchive 文件编译输出为可供安装的 TestBuildProject.ipa 文件
4. 自动编译打包脚本 ios_build.config
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # used to name the ipa APP_NAME=Demo # directory to store exported ipa APP_DIR=~/Desktop/app # the absolute path to the project directory PROJECT_DIR=/Users/reohou/Desktop/Demo # project name, the same as the .xcodeproj file name PROJECT_NAME="Demo" # scheme name SCHEME_NAME="Demo" # profile name PROFILE_NAME="adhoctag20140813" # configuration for archive CONFIGURATION="Release" # login password, to unlock login keychain LOGIN_PASSWORD="123456"
ios_build.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 # !/bin/bash function failed() { echo "Failed: $@" >&2 exit 1 } LOGIN_KEYCHAIN=~/Library/Keychains/login.keychain script_dir_relative=`dirname $0` script_dir=`cd ${script_dir_relative}; pwd` echo "script_dir = ${script_dir}" # read config. ${script_dir}/ios_build.config # unlock login keygen security unlock-keychain -p ${LOGIN_PASSWORD} ${LOGIN_KEYCHAIN} || failed "unlock-keygen" mkdir -pv ${APP_DIR} || failed "mkdir ${APP_DIR}" cd ${PROJECT_DIR} || failed "cd ${PROJECT_DIR}" rm -rf bin/* mkdir -pv bin # clean xcodebuild clean -project ${PROJECT_NAME}.xcodeproj \ -configuration ${CONFIGURATION} \ -alltargets \ || failed "xcodebuild clean" # archive xcodebuild archive -project ${PROJECT_NAME}.xcodeproj \ -scheme ${SCHEME_NAME} \ -destination generic/platform=iOS \ -archivePath bin/${PROJECT_NAME}.xcarchive \ || failed "xcodebuild archive" # export ipaxcodebuild -exportArchive -archivePath bin/${PROJECT_NAME}.xcarchive \ -exportPath bin/${PROJECT_NAME} \ -exportFormat ipa \ -exportProvisioningProfile ${PROFILE_NAME} \ -verbose \ || failed "xcodebuild export archive" # move ipa to dest directory timestamp=`date "+%Y%m%d%H"` mv bin/${PROJECT_NAME}.ipa ${APP_DIR}/${APP_NAME}_${timestamp}.ipa || failed "mv ipa" # clean bin files echo "clean bin files ..." rm -rf bin/* echo "Done."
xcode_build.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 export LC_ALL=zh_CN.GB2312; export LANG=zh_CN.GB2312 buildConfig="Release" //这里是build模式 projectName=`find . -name *.xcodeproj | awk -F "[/.]" '{print $(NF-1)}'` projectDir=`pwd` wwwIPADir=~/Desktop/$projectName-IPA isWorkSpace=true echo "~~~~~~~~~~~~~~~~~~~开始编译~~~~~~~~~~~~~~~~~~~" if [ -d "$wwwIPADir" ]; then echo $wwwIPADir echo "文件目录存在" else echo "文件目录不存在" mkdir -pv $wwwIPADir echo "创建${wwwIPADir}目录成功" fi cd $projectDir rm -rf ./build buildAppToDir=$projectDir/build infoPlist="$projectName/Info.plist" bundleVersion=`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" $infoPlist` bundleIdentifier=`/usr/libexec/PlistBuddy -c "Print CFBundleIdentifier" $infoPlist` bundleBuildVersion=`/usr/libexec/PlistBuddy -c "Print CFBundleVersion" $infoPlist` if $isWorkSpace ; then #是否用CocoaPod echo "开始编译workspace...." xcodebuild -workspace $projectName.xcworkspace -scheme $projectName -configuration $buildConfig clean build SYMROOT=$buildAppToDir else echo "开始编译target...." xcodebuild -target $projectName -configuration $buildConfig clean build SYMROOT=$buildAppToDir fi if test $? -eq 0 then echo "~~~~~~~~~~~~~~~~~~~编译成功~~~~~~~~~~~~~~~~~~~" else echo "~~~~~~~~~~~~~~~~~~~编译失败~~~~~~~~~~~~~~~~~~~" exit 1 fi ipaName=`echo $projectName | tr "[:upper:]" "[:lower:]"` #将项目名转小写 findFolderName=`find . -name "$buildConfig-*" -type d |xargs basename` #查找目录 appDir=$buildAppToDir/$findFolderName/ #app所在路径 echo "开始打包$projectName.app成$projectName.ipa....." xcrun -sdk iphoneos PackageApplication -v $appDir/$projectName.app -o $appDir/$ipaName.ipa if [ -f "$appDir/$ipaName.ipa" ] then echo "打包$ipaName.ipa成功." else echo "打包$ipaName.ipa失败." exit 1 fi path=$wwwIPADir/$projectName$(date +%Y%m%d%H%M%S).ipa cp -f -p $appDir/$ipaName.ipa $path #拷贝ipa文件 echo "复制$ipaName.ipa到${wwwIPADir}成功" echo "~~~~~~~~~~~~~~~~~~~结束编译,处理成功~~~~~~~~~~~~~~~~~~~"
效果图 (无)
备注 (无)