美文网首页寒哥管理的技术专题我的iOS开发小屋程序员
使用xcodebuild打包 导出ipa 上传蒲公英或者提交Ap

使用xcodebuild打包 导出ipa 上传蒲公英或者提交Ap

作者: 若非长得丑怎会做逗比 | 来源:发表于2016-11-06 20:11 被阅读6008次
/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Support/altool
  • 使用时如报如下错误
altool[] *** Error: 
Exception while launching iTunesTransporter: Transporter not found at path: /usr/local/itms/bin/iTMSTransporter. 
You should reinstall the application.
  • 建立软链
ln -s /Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/itms /usr/local/itms
  • 如果想要在脚本中修改plist文件的内容可以使用PlistBuddy,PlistBuddy是Mac里一个用于命令行下读写plist文件的工具,在/usr/libexec/下。可以通过它读取或修改plist文件的内容。
#!/bin/sh
# PlistBuddy程序的绝对路径
PlistBuddyPath=/usr/libexec/PlistBuddy
appInfoPlistPath="/Volumes/SourceCode/showstart_ios/ShowStart_3.0/Info.plist"
bundleShortVersion=$($PlistBuddyPath -c "print CFBundleShortVersionString" ${appInfoPlistPath})
bundleVersion=$($PlistBuddyPath  -c "print CFBundleVersion" ${appInfoPlistPath})
echo "$bundleShortVersion"
echo "$bundleVersion"

buildNumber="3.69"

bundleVersion=$($PlistBuddyPath  -c "Set :CFBundleVersion $buildNumber" ${appInfoPlistPath})
bundleVersion=$($PlistBuddyPath  -c "print CFBundleVersion" ${appInfoPlistPath})
echo "$bundleVersion"

开始打包

  • 百度了一下大多数文章使用xcodeuildxcrun编译导出ipa
xcodebuild -workspace XXX -scheme XXX -configuration Release
xcrun -sdk iphoneos PackageApplication -v "/XXX/XXX.app" -o "/XXX/XXX"
  • 另一种是xcodebuildarchive-exportArchive,然而最新需要使用--exportOptionsPlist选项,而不再使用--exportFromat
  • 使用xcodebuild -help命令可查看--exportOptionsPlist选项具体描述

如何获取工程的CODE_SIGN_IDENTITYPROVISIONING_PROFILE

  • 右键 xxx.xcodeproj 显示包内容 然后打开project.pbxproj文件
  • command F 搜索 CODE_SIGN_IDENTITY PROVISIONING_PROFILE
QQ20161106-0.png QQ20161106-1.png
  • PROVISIONING_PROFILE 使用uuid或者名称都可以

  • 注意 因为我这里打包用的Release模式所以,我在查找CODE_SIGN_IDENTITYPROVISIONING_PROFILE都是找的Release模式配置

  • 使用atool时 最终输出的xml 中包含 success-message表示成功,如果包含product-errors表示失败

  • 执行脚本

// 首先把两个plist和脚本放到工程根目录,然后打开terminal进入项目
// 第一次需要设置脚本的执行权限
chmod +x xcodebuild.sh
// 执行脚本
./xcodebuild.sh

完整的脚本 其中 xxxx 替换为你自己的

#!/bin/sh

echo "~~~~~~~~~~~~~~~~开始执行脚本~~~~~~~~~~~~~~~~"


# 开始时间
beginTime=`date +%s`
DATE=`date '+%Y-%m-%d-%T'`
#需要编译的 targetName
TARGET_NAME="xxxx"
#编译模式 工程默认有 Debug Release 
CONFIGURATION_TARGET=Release
#编译路径
BUILDPATH=~/Desktop/${TARGET_NAME}_${DATE}
#archivePath
ARCHIVEPATH=${BUILDPATH}/${TARGET_NAME}.xcarchive
#输出的ipa目录
IPAPATH=${BUILDPATH}

#证书名
CODE_SIGN_IDENTITY="xxxxx"
#描述文件
PROVISIONING_PROFILE_NAME="xxxx"

#苹果账号
AppleID="xxxx"
AppleIDPWD="xxxx"

#导出ipa 所需plist
ADHOCExportOptionsPlist=./ADHOCExportOptionsPlist.plist
AppStoreExportOptionsPlist=./AppStoreExportOptionsPlist.plist

ExportOptionsPlist=${ADHOCExportOptionsPlist}


# 是否上传蒲公英
UPLOADPGYER=false
# 是否上传AppStore
UPLOADAPPSTore=false

echo "~~~~~~~~~~~~~~~~选择打包方式~~~~~~~~~~~~~~~~"
echo "      1 ad-hoc (默认)"
echo "      2 AppStore "

# 读取用户输入并存到变量里
read parameter
sleep 0.5
method="$parameter"

# 判读用户是否有输入 
if [ -n "$method" ]
then
    if [ "$method" = "1" ]
    then 
    PROVISIONING_PROFILE_NAME="xxxx"
    ExportOptionsPlist=${ADHOCExportOptionsPlist}
    elif [ "$method" = "2" ]
    then
    UPLOADAPPSTore=true
    PROVISIONING_PROFILE_NAME="xxxx"
    ExportOptionsPlist=${AppStoreExportOptionsPlist}
    else
    echo "参数无效...."
    exit 1
    fi
else
    ExportOptionsPlist=${ADHOCExportOptionsPlist}
fi

if [ $UPLOADAPPSTore = false ]
then
    echo "~~~~~~~~~~~~~~~~是否上传蒲公英~~~~~~~~~~~~~~~~"
    echo "      1 不上传 (默认)"
    echo "      2 上传 "
    read para
    sleep 0.5

    if [ -n "$para" ]
    then
        if [ "$para" = "1" ]
        then 
        UPLOADPGYER=false
        elif [ "$para" = "2" ]
        then
        UPLOADPGYER=true
        else
        echo "参数无效...."
        exit 1
        fi
    else
        UPLOADPGYER=false
    fi
fi


echo "~~~~~~~~~~~~~~~~开始编译~~~~~~~~~~~~~~~~~~~"
echo "~~~~~~~~~~~~~~~~开始清理~~~~~~~~~~~~~~~~~~~"
# 清理 避免出现一些莫名的错误
xcodebuild clean -workspace ${TARGET_NAME}.xcworkspace \
-configuration \
${CONFIGURATION} -alltargets

echo "~~~~~~~~~~~~~~~~开始构建~~~~~~~~~~~~~~~~~~~"
#开始构建
xcodebuild archive -workspace ${TARGET_NAME}.xcworkspace \
-scheme ${TARGET_NAME} \
-archivePath ${ARCHIVEPATH} \
-configuration ${CONFIGURATION_TARGET} \
CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" \
PROVISIONING_PROFILE="${PROVISIONING_PROFILE_NAME}"

echo "~~~~~~~~~~~~~~~~检查是否构建成功~~~~~~~~~~~~~~~~~~~"
# xcarchive 实际是一个文件夹不是一个文件所以使用 -d 判断
if [ -d "$ARCHIVEPATH" ]
then
echo "构建成功......"
else
echo "构建失败......"
rm -rf $BUILDPATH
exit 1
fi
endTime=`date +%s`
ArchiveTime="构建时间$[ endTime - beginTime ]秒"


echo "~~~~~~~~~~~~~~~~导出ipa~~~~~~~~~~~~~~~~~~~"

beginTime=`date +%s`

xcodebuild -exportArchive \
-archivePath ${ARCHIVEPATH} \
-exportOptionsPlist ${ExportOptionsPlist} \
-exportPath ${IPAPATH}

echo "~~~~~~~~~~~~~~~~检查是否成功导出ipa~~~~~~~~~~~~~~~~~~~"
IPAPATH=${IPAPATH}/${TARGET_NAME}.ipa
if [ -f "$IPAPATH" ]
then
echo "导出ipa成功......"
else
echo "导出ipa失败......"
# 结束时间
endTime=`date +%s`
echo "$ArchiveTime"
echo "导出ipa时间$[ endTime - beginTime ]秒"
exit 1
fi

endTime=`date +%s`
ExportTime="导出ipa时间$[ endTime - beginTime ]秒"

# 上传AppStore
if [ $UPLOADAPPSTore = true ]
then    

    altoolPath="/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool"
    ${altoolPath} --validate-app \
    -f ${IPAPATH} \
    -u ${AppleID} \
    -p ${AppleIDPWD} \
    -t ios --output-format xml

        if [ $? = 0 ]
        then
        echo "~~~~~~~~~~~~~~~~验证ipa成功~~~~~~~~~~~~~~~~~~~"
            ${altoolPath} --upload-app \
            -f ${IPAPATH} \
            -u ${AppleID} \
            -p ${AppleIDPWD} \
            -t ios --output-format xml

            if [ $? = 0 ]
            then
            echo "~~~~~~~~~~~~~~~~提交AppStore成功~~~~~~~~~~~~~~~~~~~"
            else
            echo "~~~~~~~~~~~~~~~~提交AppStore失败~~~~~~~~~~~~~~~~~~~"
            fi
        else
        echo "~~~~~~~~~~~~~~~~验证ipa失败~~~~~~~~~~~~~~~~~~~"
        fi
else
    # 上传蒲公英 
    if [ $UPLOADPGYER = true ]
    then
        echo "~~~~~~~~~~~~~~~~上传ipa到蒲公英~~~~~~~~~~~~~~~~~~~"
        curl -F "file=@$IPAPATH" \
        -F "uKey=xxxxx" \
        -F "_api_key=xxxx" \
        -F "password=xxxxx" \
        -F "isPublishToPublic=xxxx" \
        https://www.pgyer.com/apiv1/app/upload --verbose

        if [ $? = 0 ]
        then
        echo "~~~~~~~~~~~~~~~~上传蒲公英成功~~~~~~~~~~~~~~~~~~~"
        else
        echo "~~~~~~~~~~~~~~~~上传蒲公英失败~~~~~~~~~~~~~~~~~~~"
        fi
    fi
fi



echo "~~~~~~~~~~~~~~~~配置信息~~~~~~~~~~~~~~~~~~~"
echo "开始执行脚本时间: ${DATE}"
echo "编译模式: ${CONFIGURATION_TARGET}"
echo "导出ipa配置: ${ExportOptionsPlist}"
echo "打包文件路径: ${ARCHIVEPATH}"
echo "导出ipa路径: ${IPAPATH}"

echo "$ArchiveTime"
echo "$ExportTime"
exit 1

github

相关文章

网友评论

  • 95c797dbbaa6:楼主你好!下面XXXX填什么呀
    -F "uKey=xxxxx" \
    -F "_api_key=xxxx" \
    -F "password=xxxxx" \
    -F "isPublishToPublic=xxxx" \
    若非长得丑怎会做逗比:@Sunset_e9e7 请去看蒲公英的文档 上面有说明的
  • ismilesky:楼主, 我要上传fir分发平台的话,怎么把上传蒲公英的替换成fir??
    若非长得丑怎会做逗比:@ismilesky fir 官网文档 很简单的 好像就一行命令 替换下就好了
  • 轻拂丶肩上雪:老铁 在jenkins里面做的 报错 iTunes Store operation failed:scream:
    轻拂丶肩上雪:不晓得是不是网络问题:joy:
  • 这孩子有点傻:楼主如果有多个target ,要执行某个target 打包要如何处理?
    若非长得丑怎会做逗比:@这孩子有点傻 看看 fastlane 吧 现在大部分都用着个了 比较好用 http://www.jianshu.com/p/8e571c835844
    lexiaoyao20:@这孩子有点傻 他里面的代码支持手动选择 ad-hoc和AppStore打包方式,你依葫芦画瓢也写个分支判断就行了啊
    若非长得丑怎会做逗比:@这孩子有点傻 用fastlane 吧
  • lexiaoyao20:想问一下博主:我在Xcode中勾选了 Automatically manage signing 是不是就不需要 CODE_SIGN_IDENTITY 和 PROVISIONING_PROFILE 了?
    lexiaoyao20:@凤凰天尊 对了,记得要在plist文件中添加你的teamID。
    参考页面:
    1. https://stackoverflow.com/questions/39500634/use-xcodebuild-xcode-8-and-automatic-signing-in-ci-travis-jenkins-environmen
    2. Xcode8以后的自动打包:http://fight4j.github.io/2016/11/21/xcodebuild/
    lexiaoyao20:@凤凰天尊 我试了下在Xcode勾选了 Automatically manage signing,如果使用CODE_SIGN_IDENTITY和PROVISIONING_PROFILE这两个参数,就会 archive 失败。 然后我就去掉了这两个参数,就可以 archive 成功了,也能正常安装。
    凤凰天尊:朋友你这个问题找到答案了吗
  • zhaowensky_3585:github 上的脚本需要更新一下 line:132
    xcodebuild archive -xcodeproj ${PROJECTNAME}.xcodeproj
    应该替换为
    xcodebuild archive -project ${PROJECTNAME}.xcodeproj \
    若非长得丑怎会做逗比:@zhaowensky_3585 好的 以更新
    zhaowensky_3585:exit 1 最后一行,如何使用Jenkins构建,其实是成功的,但由于不是exit 0,会认为构建失败
  • Ashen:博主你好,我想问下,设置苹果开发者账号时,必须是主账号吗?我的是授权账号,为什么使用altool时报密码或账号错误呢
    Ashen:@Sias_Orange 人家的教程都这么简明了,再不会我也没法了,另外推荐你看看fastlane打包,更简单便捷
    Sias_Orange:@Ashen 我还是不知道怎么用的 阿婶:smiley:
    Ashen:我找到原因了,因为我的密码中含有&字符,我没有使用反转符,导致密码错误
  • GTMYang:The following build commands failed:
    Ld /Users/luoyang/Library/Developer/Xcode/DerivedData/Olliix-clccvgokiocjyrbgdyosxucbkgni/Build/Intermediates/ArchiveIntermediates/Olliix/IntermediateBuildFilesPath/Olliix.build/Release-iphoneos/Olliix.build/Objects-normal/armv7/Olliix normal armv7
    Ld /Users/luoyang/Library/Developer/Xcode/DerivedData/Olliix-clccvgokiocjyrbgdyosxucbkgni/Build/Intermediates/ArchiveIntermediates/Olliix/IntermediateBuildFilesPath/Olliix.build/Release-iphoneos/Olliix.build/Objects-normal/arm64/Olliix normal arm64
    (2 failures)
    GTMYang:楼主,这个是怎么回事?
  • 1a392df793c3:#证书名
    CODE_SIGN_IDENTITY="xxxxx"
    #描述文件
    PROVISIONING_PROFILE_NAME="xxxx" 这个证书名和描述文件到底是啥啊,打开钥匙串不知道要用证书的哪些信息
  • fdb60a43418c:/Applications/Xcode.app/Contents/Applications/Application: No such file or directory我在验证app的时候跳出这个东西,路径不对吗?我试了很多遍了
    段帅帅:altoolPath='/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool'
    "$altoolPath" --validate-app \
    -f ${IPAPATH} \
    -u ${AppleID} \
    -p ${AppleIDPWD} \
    -t ios --output-format xml
    软连接也建立了 ,路径改了也不知道多少遍了 就是 找不到 求救!~
    dangxiao_AppStore.sh: line 107: /Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool: No such file or directory
    fdb60a43418c:@若非长得丑怎会做逗比 已解决,路径使用单引号,引用时"$altoolPath"
  • 若非长得丑怎会做逗比:xcodebuild -list 看看输出的target有哪些
  • zedxpp:我的项目是Swift3的 依赖了 SnapKit TARGET_NAME="xxxx"已经换成我的了 但是我打包的时候, 怎么老是跑到SnapKit上去了? 然后导致构建失败
    === BUILD TARGET SnapKit OF PROJECT Pods WITH CONFIGURATION Release ===
    zedxpp:@若非长得丑怎会做逗比 确定没错。填的name是我项目名,再错也不会错成snapkit吧。
    若非长得丑怎会做逗比:@粉红色的星空 你搞错了吧
  • 十一岁的加重:貌似是用python写的
    d725421af5ee:@十一岁的加重 大哥,这是用shell写的吧!
  • cjnwan:请问下如果有多个target,PROVISIONING_PROFILE_NAME怎么设置,是设置多个吗
    若非长得丑怎会做逗比:@cjnwan 你改 xxxx 的就是了啊 PROVISIONING_PROFILE_NAME 这是脚本里面定义的变量
    仔细看脚本吧
    cjnwan:@若非长得丑怎会做逗比 xcodebuild archive -workspace ${TARGET_NAME}.xcworkspace \
    -scheme ${TARGET_NAME} \
    -archivePath ${ARCHIVEPATH} \
    -configuration ${CONFIGURATION_TARGET} \
    CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" \
    PROVISIONING_PROFILE="${PROVISIONING_PROFILE_NAME}" 那个这个命令改怎么写呢
    若非长得丑怎会做逗比:@cjnwan 对应的target build settings Provisioning Profile 查看

本文标题:使用xcodebuild打包 导出ipa 上传蒲公英或者提交Ap

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