惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页
Forbes - Security
Forbes - Security
WordPress大学
WordPress大学
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
L
LINUX DO - 热门话题
L
Lohrmann on Cybersecurity
Spread Privacy
Spread Privacy
D
Darknet – Hacking Tools, Hacker News & Cyber Security
大猫的无限游戏
大猫的无限游戏
博客园 - 三生石上(FineUI控件)
P
Privacy International News Feed
A
About on SuperTechFans
T
Tailwind CSS Blog
I
InfoQ
S
Securelist
云风的 BLOG
云风的 BLOG
罗磊的独立博客
Recent Announcements
Recent Announcements
T
The Exploit Database - CXSecurity.com
B
Blog RSS Feed
V
Visual Studio Blog
Know Your Adversary
Know Your Adversary
The GitHub Blog
The GitHub Blog
Jina AI
Jina AI
腾讯CDC
Cyberwarzone
Cyberwarzone
有赞技术团队
有赞技术团队
AWS News Blog
AWS News Blog
博客园 - 【当耐特】
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
F
Full Disclosure
S
Secure Thoughts
博客园 - 司徒正美
J
Java Code Geeks
Y
Y Combinator Blog
Google Online Security Blog
Google Online Security Blog
GbyAI
GbyAI
N
News and Events Feed by Topic
Help Net Security
Help Net Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Project Zero
Project Zero
T
Tenable Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Tor Project blog
MyScale Blog
MyScale Blog
Scott Helme
Scott Helme
小众软件
小众软件
K
Kaspersky official blog

壹拾肆

2024 年做过的一些梦 2023 年做过的一些梦 2023 年终总结丨随时开始奔跑的心气 2022 年终总结丨惠存这一年 翻译:Why use dependency injection 是时候维护一个属于自己的开源库了 iOS 端豆瓣开源许可提到的库 推荐几个播客节目 业余剪辑自我修养 Swift - 权限请求封装 iOS - HMAC 加密算法和一个 MD5 加密的问题 iOS - 一些蓝牙问题的解决 Swift - 顶部弹出框封装 被光放弃的人 OC - 多代理的实现 我的 AIO-notion 工作流搭建 解决使用 GitPage 重定向多次问题 Swift - ?和!的学习 《文学回忆录》读书笔记
iOS 自动化打包上传 AppleStore、fir.im,并发邮件通知测试人员
Kaaaaai · 2020-10-19 · via 壹拾肆

workflow

从上图可以看出使用自动化出包,可以优化掉好几个需要人工介入的步骤,优化开发流程,节省开发者的时间。

自动打包的原理概不累述了,测试过程中如果有问题,可以用终端 cd 到项目目录,单独执行出问题的语句,再把错误的输出丢到搜索引擎,只要相信你遇到的问题别人肯定也会遇到,就一定能得到解决。如果有例外,那我相信——能弄出史无前例的问题的你,一定也厉害到可以史无前例的予以解决~当然也可以试着给我留言,说不定三个臭皮匠果真赛过诸葛亮。

脚本内容基本是基于网络上内容,做了整合,修复了一些可能会导致打包失败的错误。将打印添加颜色输出,以及添加了一些注释。

一、参考

延伸知识:多渠道自动打包

二、脚本源码

已做脱敏处理。

自动打包并上传

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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170




SECONDS=0


project_name=xxxxx


scheme_name=xxxxx


info_plist_name="Info"


development_mode=Release


fir_token="xxxxx"



apple_account="xxxxx"
apple_password="xxxxx"



project_path=$(cd `dirname $0`; pwd)

archive_path=${project_path}/PackageArchived


build_path=${project_path}/AutoBuild


exportOptionsPlistPath=${project_path}/exportTest.plist


DATE=`date '+%Y-%m-%d-%H-%m-%S'`


exportIpaPath=${archive_path}/${development_mode-$DATE}


version=$(sed -n '/MARKETING_VERSION/{s/MARKETING_VERSION = //;s/;//;s/^[[:space:]]*//;p;q;}' ${project_name}.xcodeproj/project.pbxproj)


ipa_name="$scheme_name-v$version"


if [ ! -d "$archive_path" ];
then
mkdir -p "$archive_path";
else
rm -rf "$archive_path"
mkdir -p "$archive_path"
fi

if [ -d "$build_path" ]; then

rm -rf "$build_path"
mkdir -p "$build_path"
fi

echo "\033[34;1m请选择打包方式(输入序号,按回车即可) \033[0m"
echo "\033[32;1m1:app-store \033[0m"
echo "\033[32;1m2:ad-hoc \033[0m"

read number
while([[ $number != 1 ]] && [[ $number != 2 ]])
do
echo "\033[31m错误! 请输入 1 或者 2\033[0m"
echo "\033[34;1m请选择打包方式(输入序号,按回车即可) \033[0m"
echo "\033[32;1m1:app-store \033[0m"
echo "\033[32;1m2:ad-hoc \033[0m"
read number
done

if [ $number == 1 ];then
development_mode=Release
exportOptionsPlistPath=${project_path}/exportAppstore.plist
else
development_mode=Debug
exportOptionsPlistPath=${project_path}/exportTest.plist
fi

echo '\033[33;1m///-----------\033[0m'
echo '\033[33;1m/// 正在清理工程\033[0m'
echo '\033[33;1m///-----------\033[0m'

xcodebuild \
clean -configuration ${development_mode} -quiet || exit

echo '\033[32;1m///--------\033[0m'
echo '\033[32;1m/// 清理完成\033[0m'
echo '\033[32;1m///--------\033[0m'
echo ''

echo '\033[33;1m///-------------\033[0m'
echo "\033[33;1m/// 正在编译工程: ${development_mode}\033[0m"
echo '\033[33;1m///-------------\033[0m'
xcodebuild \
archive -workspace ${project_path}/${project_name}.xcworkspace \
-scheme ${scheme_name} \
-configuration ${development_mode} \
-archivePath ${build_path}/${project_name}.xcarchive -quiet || exit

echo '\033[32;1m///-------------\033[0m'
echo '\033[32;1m/// 编译完成 \033[0m'
echo '\033[32;1m///-------------\033[0m'
echo ''

echo '\033[33m///-------------\033[0m'
echo '\033[33m/// 开始ipa打包\033[0m'
echo '\033[33m///-------------\033[0m'
xcodebuild -exportArchive -archivePath ${build_path}/${project_name}.xcarchive \
-configuration ${development_mode} \
-exportPath ${exportIpaPath} \
-exportOptionsPlist ${exportOptionsPlistPath} \
-allowProvisioningUpdates \
-quiet || exit


mv $exportIpaPath/$scheme_name.ipa $exportIpaPath/$ipa_name.ipa

if [ -e $exportIpaPath/$ipa_name.ipa ]; then
echo '\033[32;1m///-------------\033[0m'
echo "\033[32;1m导出 ${ipa_name}.ipa 包成功 🎉🎉🎉 \033[0m"
echo '\033[32;1m///-------------\033[0m'
open $exportIpaPath

rm -rf "$build_path"
else
echo '\033[31;1m///-------------\033[0m'
echo "\033[31;1m导出 ${ipa_name}.ipa 包失败 💔💔💔 \033[0m"
echo '\033[31;1m///-------------\033[0m'
exit 1
fi
echo '\033[36;1m///-------------\033[0m'
echo "\033[36;1m/// 打包 ipa 完成。总耗时:${SECONDS}s \033[0m"
echo '\033[36;1m///-------------\033[0m'
echo ''

echo '\033[33m///-------------\033[0m'
echo '\033[33m/// 开始发布ipa包 \033[0m'
echo '\033[33m///-------------\033[0m'

if [ $number == 1 ];then



altoolPath="/Applications/Xcode.app/Contents/SharedFrameworks/ContentDeliveryServices.framework/Versions/A/Frameworks/AppStoreService.framework/Versions/A/Support/altool"
"$altoolPath" --validate-app -f ${exportIpaPath}/${ipa_name}.ipa -u $apple_account -p $apple_password -t ios --output-format xml
"$altoolPath" --upload-app -f ${exportIpaPath}/${ipa_name}.ipa -u $apple_account -p $apple_password -t ios --output-format xml
else


fir login -T $fir_token
fir publish $exportIpaPath/$ipa_name.ipa --skip-update-icon

echo '\033[33m///-------------\033[0m'
echo '\033[33m/// 开始发送邮件给测试人员 \033[0m'
echo '\033[33m///-------------\033[0m'


python sendEmail.py "测试版本 (iOS)xxxxx v(${version}) 上传成功" "赶紧下载体验吧:xxxxx"
fi

exit 0

上传成功成功后发送邮件

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





import sys
import smtplib
import io
from email.mime.text import MIMEText
from email.header import Header
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart

sender = '[email protected];'


to_receiver = ['xxxxx','xxxxx']

cc_receiver = ['xxxxx']
smtpserver = 'smtp.exmail.qq.com'

smtpport = 465

//smtp 配置,需要到邮箱账户设置界面自行获取
username = 'xxxxx'
password = 'xxxxx'








def send_mail(title, content):

try:
subject = title

msg = MIMEMultipart("related")



if not isinstance(title,unicode):
title = unicode(title, 'utf-8')
msg['Subject'] = title
msg['From'] = sender
msg['To'] = ";".join(to_receiver)
msg['Cc'] = ";".join(cc_receiver)
msg["Accept-Language"]="zh-CN"
msg["Accept-Charset"]="ISO-8859-1,utf-8"


msgText = MIMEText(content,'plain','utf-8')
msg.attach(msgText)









to_addrs=to_receiver+cc_receiver
smtp = smtplib.SMTP_SSL(smtpserver,smtpport)
smtp.login(username, password)
smtp.sendmail(sender, to_addrs, msg.as_string())
smtp.quit()
return True
except Exception, e:
print str(e)
return False

if send_mail(sys.argv[1], sys.argv[2]):
print "🎉🎉🎉发送成功!"
else:
print "❌❌❌发送失败!"

三、问题

上传工具路径不对问题

解决方法来源:xcode11 构建上传问题

从原来的

1
/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool

变为了

1
/Applications/Xcode.app/Contents/SharedFrameworks/ContentDeliveryServices.framework/Versions/A/Frameworks/AppStoreService.framework/Versions/A/Support/altool

$(MARKETING_VERSION) 获取版本号失败

解决方法来源:How to handle $(MARKETING_VERSION) of Xcode 11 by CI

使用一下语句获取

1
2
3
4
5
6
7

version=$(sed -n '/MARKETING_VERSION/{s/MARKETING_VERSION = //;s/;//;s/^[[:space:]]*//;p;q;}' {your project name}.xcodeproj/project.pbxproj)

if [ -z "${version}" ]; then
echo "[ERROR] failed to get MARKETING_VERSION"
exit 1
fi

错误信息:

1
2
3
4
5
Error: Errors uploading 'xxx.ipa': (
"Error Domain=ITunesSoftwareServiceErrorDomain Code=-22014 \"We are unable to create an authentication session.\"
UserInfo={NSLocalizedDescription=We are unable to create an authentication session., NSLocalizedFailureReason=Unable to
validate your application.}"
)

解决方式:到 https://appleid.apple.com 生成一个专用密码就行了,然后用这个密码改到上面去,再次执行。即:xcrun altool --upload-app -f a/b/xxx.ipa -u [[email protected]](mailto:[email protected]) -p 生成的专用密码