1、前言
在上传提交ipa文件成功后,发现AppStoreConnect后台一直不显示构建版本,最后邮箱收到:
App Store Connect
Dear Developer,
We identified one or more issues with a recent delivery for your app, “XXX”. Please correct the following issues, then upload again.
Invalid Executable Size - The size of your app’s executable file ‘XXX.app/XXX’ is 90374144 bytes, which exceeds the maximum allowed size of 80 MB.
Best regards,
The App Store Team
2、原因
Executable Size
?executable file
?这2个是什么东西?Executable 是可执行的意思,所以就是可执行的大小、可执行的文件。
每个 Mach-O 可执行文件(例如,app_name.app/app_name)不得超过这些正文段(__TEXT)文件大小的上限。具体 Mach-O 和 __TEXT 是什么,大家可以看看:ObjC 中国 - Mach-O 可执行文件。
那从苹果文档最大构建版本文件大小 - App Store Connect 帮助,可以得到如下:
OS 版本 | 最大可执行文件大小 | 备注 |
---|---|---|
iOS 9.0 或更高版本 Apple TVOS 9.0 或更高版本 |
500 MB | 针对二进制文件中所有“__TEXT”部分的总和。 |
iOS 7.X 至 iOS 8.X | 60 MB | 针对每个 Architecture Slice(架构片段)中的“__TEXT”部分。 |
低于 iOS 7.0 | 80 MB | 针对二进制文件中所有“__TEXT”部分的总和。 |
- 注:Architecture Slice(架构片段)是针对特定架构的胖二进制布局文件的一部分。例如,一个胖二进制文件可能会包含针对 32 位和 64 位架构的片段。
综上,executable file 'XXX.app/XXX' is 90374144 bytes, which exceeds the maximum allowed size of 80 MB.
就是说,当前可执行文件“__TEXT”部分的总和为 90374144 bytes
,超过了 80 MB
。
是什么?
当前可执行文件“__TEXT”部分的总和大小超过80MB!为什么?
Mach-O可执行文件中包含__TEXT
区域,__TEXT
包含了被执行的代码,即编译所得到的机器码。所以,也就是我们的应用中代码量或引用的第三方库过大导致。怎么办?
因为苹果限制,所以,- 第1步是减少第三方库或删除无用的代码。
- 第2步是要找到什么计算
__TEXT
的大小?
3、__TEXT
大小计算
怎么计算 __TEXT
的 size
? 在终端用 size XXX
就可以打印当前应用的二进制的__TEXT
字段大小:
1 | ➜ ~ size /Users/HTC/Downloads/WeChat/Payload/WeChat.app/WeChat |
注:如果应用支持armv7
、arm64
多种架构,就会显示多个,不会有i386
、x86_64
是因为dis正式包已经移除模拟器架构。像现在新的应用,只支持arm64
就不会显示具体架构:
1 | ➜ ~ size /Users/HTC/Downloads/Weixin/Payload/WeChat.app/WeChat |
那么知道了计算公式,根据上面苹果给出的文档要求,需要做应用最低支持系统版本判断计算方式:
- iOS 7.X 至 iOS 8.X 每个架构最大为 60 MB
- iOS 9.0 或更高版本 500 MB 针对二进制文件中所有“__TEXT”部分的总和。
- 低于 iOS 7.0 80 MB 针对二进制文件中所有“__TEXT”部分的总和。
根据这个要求,会出现如下2种计算方式:
- 计算所有“__TEXT”部分的总和
1 | size app | awk '{print $1}' | grep -E '[0-9]' | awk '{sum += $1}; END {print sum}' |
运行示例:
1 | ➜ ~ size /Users/HTC/Downloads/WeChat/Payload/WeChat.app/WeChat | awk '{print $1}' | grep -E '[0-9]' | awk '{sum += $1}; END {print sum}' |
脚本说明:首先是用size
列出全部的架构的__TEXT
大小,然后用 awk
(awk文本处理实战 | opengers)过滤出第一列的内容输出,然后用grep
-E(扩展的正则表达式)过滤数字的行,最后是计算各行数字相加的和输出。
- 分别列出各架构的大小
1 | size app | awk '{print $1 "," $10}' | tail -n +2 |
运行示例:
1 | ➜ ~ size /Users/HTC/Downloads/WeChat/Payload/WeChat.app/WeChat | awk '{print $1 "," $10}' | tail -n +2 |
脚本说明:首先是用size
列出全部的架构的__TEXT
(第1列)大小和架构名(第10列),之前用分号,
间隔,然后输出,然后用 tail
输出从第2行开始的内容。
以上就是本文的核心内容,具体shell的技巧就不深讲啦,大家有兴趣可以搜索,awk
、tail
命令了解更多,awk文本处理实战 | opengers、Linux tail 命令 | 菜鸟教程
4、shell 编程实现
需要注意一下,上面输出的是bytes,而macOS是用1000来转换成MB。
所有版本的Windows系统都会将一个2^20 bytes的文件显示为“1.00MB”,而10^6 bytes的文件显示为976kB。在Mac OS X 10.6之后将文件和磁盘大小都用Megabytes来表示,即将10^6 bytes的文件显示为1MB。
最终效果示例:
1 | ================================================ |
具体的代码,可参考我的Github代码:
calculate_Mach-0__Text-Size .sh
:
1 | !/bin/bash |
5、总结
本次脚本又顺利提高了效率!本文用到非常多的脚本命令,大家不必说记住,主要是知道用来做什么的,或者有需求时要搜索也可以,通过本次脚本编写,大家应该能发现shell脚本的强大而洁的语法,要学到以用,还需要多实践!
参考
- iHTCboy/iShell: Shell脚本编程技巧,总结一些常用的提高效率的方法。
- 最大构建版本文件大小 - App Store Connect 帮助
- ipa上传app store的大小限制 - 逸轻紫的博客 - CSDN博客
- How can i reduce __TEXT segment size? |Apple Developer Forums
- xcode - How can i reduce __TEXT segment size in iOS App? - Stack Overflow
- Mach-O 文件格式探索 · 瓜地
- ios - How to measure the code (i.e. data + text) size of a static library? - Stack Overflow
- awk文本处理实战 | opengers
- Linux tail 命令 | 菜鸟教程
- Mebibyte - 维基百科,自由的百科全书
- iOS预审总被拒?腾讯教你提升iOS审核通过率! - wetest_tencent的博客 - CSDN博客
- shell比较浮点数和整数 - breezey - 博客园
- Shell中将分隔符的字符串转为数组的几种方法 - 杰瑞的专栏 - CSDN博客
- shell 字符串转数组 数组转字典 - 波波诸葛伟 - CSDN博客
- 如有疑问,欢迎在评论区一起讨论!
- 如有不正确的地方,欢迎指导!
> 注:本文首发于 [iHTCboy's blog](https://iHTCboy.com),如若转载,请注来源