脚本化生成 ipa 并上传至第三方托管

  • 目录
  • 简介
  • 环境
  • 关键点分析
  • 源码
  • 效果图
  • 遇到的问题
  • 致谢

简介

项目进行一定阶段的时候,需要给团队中的QA同学(但不局限于QA)安装app

有时候修复了几个bug后,瞬间七八个手机飞到面前,感觉像是医生给病人打针一样,biu~ 下一个~ biu~ 下一个~ biu~ 下一个~ biu~ 下一个~ biu~ 下一个~...

一般可以把测试版的app放到第三方托管网站上(比如笔者使用的蒲公英),打包后可以把ipa上传,然后需要安装的同学可以直接扫码或者safari打开链接安装即可

然后就变成了,打包 --> 上传

偶尔几次倒还可以接受,但机械重复的动作总是让人烦躁

于是乎,只能抽时间研究研究自动化脚本(一个命令执行打包成ipa,并上传到蒲公英)


环境

笔者环境


关键点分析,一些相关命令说明,时间紧的同学可以直接拖到源码部分

可以 $ man xcodebuild

  1. Xcode中如果执行command b 或者 command r时候,其实相当于先执行xcodebuild,然后xcrun(实际操作中,会出现问题,见下文问题总结)或者 xcodebuild -exportArchive
  2. xcodebuild命令
    首先cd到项目根目录
  • xcodebuild -version 查看Xcode的版本号和build版本
ff:ff fengfeng$ xcodebuild -version
Xcode 9.3
Build version 9E145
ff:ff fengfeng$
  • xcodebuild -list 查看项目全部的
 ff:ff fengfeng$ xcodebuild -list
 Information about project "***":
 Targets:
     ff

 Build Configurations:
     Debug
     Release
     discribution

 If no build configuration is specified and -scheme is not passed then "Release" is used.

 Schemes:
     ff

 ff:ff fengfeng$ 
  • xcodebuild -showsdks 查看可以使用的sdk
 ff:ff fengfeng$ xcodebuild -showsdks  
 iOS SDKs:
 iOS 11.3                        -sdk iphoneos11.3

 iOS Simulator SDKs:
 Simulator - iOS 11.3            -sdk iphonesimulator11.3

 macOS SDKs:
 macOS 10.13                     -sdk macosx10.13

 tvOS SDKs:
 tvOS 11.3                       -sdk appletvos11.3

 tvOS Simulator SDKs:
 Simulator - tvOS 11.3           -sdk appletvsimulator11.3

 watchOS SDKs:
 watchOS 4.3                     -sdk watchos4.3

 watchOS Simulator SDKs:
 Simulator - watchOS 4.3         -sdk watchsimulator4.3
 ff:ff fengfeng$ 
  • xcodebuild build [-optionName ...] 适用于workspace编译
xcodebuild build -workspace ***.xcworkspace \
-scheme *** \
-configuration Debug \
-sdk iphoneos11.3
参数 说明
-workspace ***.xcworkspace 工作空间文件
-scheme *** 构建工程名称
-configuration [Debug/Release] 构建Debug或者Release
-sdk iphoneos11.3 指定编译时使用的SDK
  • xcodebuild archive [-optionName ...] 编译生成. xcarchive
xcodebuild archive -archivePath /***/*** \
-workspace ***.xcworkspace \
-scheme *** \
-configuration Debug \
-sdk iphoneos11.3
参数 说明
-archivePath /***/*** 保存生成.xcarchive包的路径
-workspace ***.xcworkspace 工作空间文件
-scheme *** 构建工程名称
-configuration [Debug/Release] 构建Debug或者Release
-sdk iphoneos11.3 指定编译时使用的SDK
  • xcodebuild -exportArchive [-optionName ...] .archive包导出ipa文件
xcodebuild -exportArchive \
-archivePath /xx/xx/xx.xcarchive \
-exportPath /xx/xx/xx \
-exportOptionsPlist /xx/xx/xx.plist
参数 说明
-archivePath xcodebuild archive [-optionName ...] 编译生成. xcarchive
-exportPath 导出的ipa保存的目录
-exportOptionsPlist 导出时 需要的 配置文件的 路径
  • 详细的exportOptionsPlist看👇,如果不知道怎么写的话,可以先手动打包需要的版本,打包成功的文件夹中会有exportOptionsPlist,可以复制一份到某个地方,给上面的命令使用即可
  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 <plist version="1.0">
  4 <dict>
  5         <key>compileBitcode</key>
  6         <false/>
  7         <key>method</key>
  8         <string>development</string>
  9         <key>provisioningProfiles</key>
 10         <dict>
 11                 <key>com.***</key>
 12                 <string>***</string>
 13         </dict>
 14         <key>signingCertificate</key>
 15         <string>iPhone Developer</string>
 16         <key>signingStyle</key>
 17         <string>manual</string>
 18         <key>stripSwiftSymbols</key>
 19         <true/>
 20         <key>teamID</key>
 21         <string>***</string>
 22         <key>thinning</key>
 23         <string>&lt;none&gt;</string>
 24 </dict>
 25 </plist>
  • xcodebuild clean [-optionName ...]清除编译过程生成文件
xcodebuild clean -workspace ***.xcworkspace \
-scheme *** \
-configuration Debug \
-sdk iphoneos11.3
参数 说明
-workspace ***.xcworkspace 工作空间文件
-scheme *** 构建工程名称
-configuration [Debug/Release] 构建Debug或者Release
-sdk iphoneos11.3 指定编译时使用的SDK
  1. 编译和提取ipa的主要命令就是👆介绍的,现在说明下如何将打包好的ipa上传到蒲公英
    a. 准备 API Key User Key password
    如何查看 API Key User Key:登录蒲公英 - 右上角 - 账户设置 - API 信息

    b. 使用如下命令,注意file=后面的@

    curl -F "file=@/***/***/***.ipa" \
    -F "uKey=user_key" \
    -F "_api_key=api_key" \
    -F "password=pwd" \
    https://qiniu-storage.pgyer.com/apiv1/app/upload 
    

    c. 如果上传后,会返回一串json,错误说明,或者成功信息
    上传成功后返回的数据,格式化后如下

     {
         "code":0,
         "message":"",
         "data":{
             "appKey":"***",
             "userKey":"***",
             "appType":"1",
             "appIsLastest":"1",
             "appFileSize":"***",
             "appName":"***",
             "appVersion":"1.3",
             "appVersionNo":"1",
             "appBuildVersion":"6",
             "appIdentifier":"***",
             "appIcon":"***",
             "appDescription":"***",
             "appShortcutUrl":"***",
             "appCreated":"2018-06-17 22:03:56",
             "appUpdated":"2018-06-17 22:03:56",
             "appQRCodeURL":"***"
         }
     }
    

源码

使用复制下面源码,将各种路径和配置依据实际情况配置正确,然后终端执行即可
默认生成的是Develop版本,因为笔者公司提交app store要求专人打包
使用前 需要提前 切换好分支或者 git pull

哈哈,从此,一键上传,然后把生成的链接或者二维码给相关同学即可,再也不用,一个手机一个手机的打针了 ~

#!/bin/bash

scheme_name=***
branch_name=develop
configuration=Develop
date=`date +%Y%m%d_%H%M%S`

# 项目根路径
source_path="/***/***/"
# 打包生成的文件 所在的文件夹
ipa_root_path="/***/***"
# .xcarchive 文件所在的文件夹
ipa_build_path=$ipa_root_path"/build/"
# 生成的 .xcarchive文件 (不带后缀 .xcarchive)
ipa_build_result_path=$ipa_build_path$date
# 打包成功后生成的文件夹名,由分支、时间组成
ipa_name=$branch_name"_"$date
# -exportOptionsPlist 需要的 plist 文件的路径
plist_path="/***/***/***.plist"

# 如果有 .xcarchive 文件,移动至垃圾桶 或者 删除之
if ! [ "`ls $ipa_build_path`" = "" ]; then  
    # mv $ipa_build_path/* ~/.Trash
    rm -rf $ipa_build_path/*
    if [ $? -ne 0 ]; then
        echo "~~~~~~~~ delete files failed ~~~~~~~~"
        exit 1
    fi
fi

# build ***.xcworkspace

# 已废弃
# xcodebuild \
# -workspace $source_path"/"$scheme_name".xcworkspace" \
# -scheme $scheme_name \
# -configuration Debug \
# clean \
# build \
# -derivedDataPath $ipa_build_result_path

xcodebuild \
archive -archivePath $ipa_build_result_path \
-workspace $source_path$scheme_name".xcworkspace" \
-scheme $scheme_name \
-configuration $configuration

if [ -e $ipa_build_result_path".xcarchive" ]; then
    echo "~~~~~~~~ xcodebuild successful ~~~~~~~~"
else 
    echo "~~~~~~~~ xcodebuild failed ~~~~~~~~"
    exit 1
fi

# xcrun ***.ipa
# 已废弃
# xcrun -sdk iphoneos PackageApplication \
# -v $ipa_build_result_path/Build/Products/Debug-iphoneos/$scheme_name.app \
# -o $ipa_path/$ipa_name

xcodebuild -exportArchive \
-archivePath $ipa_build_result_path.xcarchive \
-exportPath $ipa_root_path/$ipa_name \
-exportOptionsPlist $plist_path

if [ -e $ipa_root_path/$ipa_name ]; then
    echo -e "creat ipa successful\n"
    open $ipa_root_path/$ipa_name
else
    echo "creat ipa failed"
    exit 1
fi

# 上传至蒲公英
# ipa路径
pgy_ipa_path=$ipa_root_path/$ipa_name/$scheme_name".ipa"
pgy_api_key="***"
pgy_user_key="***"
pgy_pwd="***"

echo "-------->>>>>> 上传ipa到蒲公英 <<<<<<--------"  

curl -F "file=@${pgy_ipa_path}" \
-F "uKey=${pgy_user_key}" \
-F "_api_key=${pgy_api_key}" \
-F "password=${pgy_pwd}" \
https://qiniu-storage.pgyer.com/apiv1/app/upload 

if [ $? = 0 ]; then  
    echo -e "\n"
    echo "-------->>>>>> 上传蒲公英成功 <<<<<<--------"  
else  
    echo -e "\n"
    echo "-------->>>>>> 上传蒲公英失败 <<<<<<--------"  
fi 

效果图

遇到的问题
  1. xcrun: error: unable to find utility "PackageApplication", not a developer tool or in PATH creat ipa failed
    Xcode 8.3移除了PackageApplication,使用archive
    或者 参考:https://stackoverflow.com/questions/43068608/xcrun-error-unable-to-find-utility-packageapplication-not-a-developer-tool/43185342

2.requires a provisioning profile
exportOptionsPlist文件格式错误,缺少provisioningProfiles
可以正常手动打包,并且导出为对应的ipa,然后在生成的ipa所在的文件中有ExportOptions.plist文件,可以使用这个即可

error: exportArchive: "***.app" requires a provisioning profile with the Associated Domains and Push Notifications features.

Error Domain=IDEProvisioningErrorDomain Code=9 ""***.app" requires a provisioning profile with the Associated Domains and Push Notifications features." UserInfo={NSLocalizedDescription="***.app" requires a provisioning profile with the Associated Domains and Push Notifications features., NSLocalizedRecoverySuggestion=Add a profile to the "provisioningProfiles" dictionary in your Export Options property list.}

** EXPORT FAILED **

2018.06.29
尴尬,用了一段时间后,结果又要一个个的来了


不定期更新 不合适的地方 还请指点~ 感激不尽

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352