shell技巧6 - iOS最大构建版本文件大小
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
字段大小:
~ size /Users/HTC/Downloads/WeChat/Payload/WeChat.app/WeChat __TEXT __DATA __OBJC others dec hex 53329920 7929856 0 3162112 64421888 3d70000 /Users/HTC/Downloads/WeChat/Payload/WeChat.app/WeChat (for architecture armv7) 57475072 13647872 0 4298047488 4369170432 1046c4000 /Users/HTC/Downloads/WeChat/Payload/WeChat.app/WeChat (for architecture arm64) ~
注:如果应用支持armv7
、arm64
多种架构,就会显示多个,不会有i386
、x86_64
是因为dis正式包已经移除模拟器架构。像现在新的应用,只支持arm64
就不会显示具体架构:
~ size /Users/HTC/Downloads/Weixin/Payload/WeChat.app/WeChat __TEXT __DATA __OBJC others dec hex 65355776 15040512 0 4298145792 4378542080 104fb4000
那么知道了计算公式,根据上面苹果给出的文档要求,需要做应用最低支持系统版本判断计算方式:
- iOS 7.X 至 iOS 8.X 每个架构最大为 60 MB
- iOS 9.0 或更高版本 500 MB 针对二进制文件中所有“__TEXT”部分的总和。
- 低于 iOS 7.0 80 MB 针对二进制文件中所有“__TEXT”部分的总和。
根据这个要求,会出现如下2种计算方式:
- 计算所有“__TEXT”部分的总和
size app | awk '{print $1}' | grep -E '[0-9]' | awk '{sum += $1}; END {print sum}'
运行示例:
~ size /Users/HTC/Downloads/WeChat/Payload/WeChat.app/WeChat | awk '{print $1}' | grep -E '[0-9]' | awk '{sum += $1}; END {print sum}' 110804992
脚本说明:首先是用size
列出全部的架构的__TEXT
大小,然后用 awk
(awk文本处理实战 | opengers)过滤出第一列的内容输出,然后用grep
-E(扩展的正则表达式)过滤数字的行,最后是计算各行数字相加的和输出。
- 分别列出各架构的大小
size app | awk '{print $1 "," $10}' | tail -n +2
运行示例:
~ size /Users/HTC/Downloads/WeChat/Payload/WeChat.app/WeChat | awk '{print $1 "," $10}' | tail -n +2 53329920,armv7) 57475072,arm64)
脚本说明:首先是用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。
最终效果示例:
================================================ Enter Mach-O executable file path: /Users/HTC/Downloads/WeChat/Payload/WeChat.app/WeChat Place enter the number select minimum supported system version for the app? [ 1:gt iOS9 2:lt iOS7 3:iOS7.X~8.X] 1 executable file size: 110.805 MB ⭕️ [Success] 110.805 MB, 符合苹果 iOS9 小于 500 MB 的要求! ================================================ Enter Mach-O executable file path: /Users/HTC/Downloads/WeChat/Payload/WeChat.app/WeChat Place enter the number select minimum supported system version for the app? [ 1:gt iOS9 2:lt iOS7 3:iOS7.X~8.X] 2 executable file size: 110.805 MB [Error] 110.805 MB, 不符合苹果 iOS7 小于 80 MB 的要求! ================================================ Enter Mach-O executable file path: /Users/HTC/Downloads/WeChat/Payload/WeChat.app/WeChat Place enter the number select minimum supported system version for the app? [ 1:gt iOS9 2:lt iOS7 3:iOS7.X~8.X] 3 armv7 executable file size: 53.3299 MB ⭕️ [Success] armv7 size: 53.3299 MB, 符合苹果 iOS 7.X 至 iOS 8.X 每个架构最大为 60 MB 的要求! arm64 executable file size: 57.4751 MB ⭕️ [Success] arm64 size: 57.4751 MB, 符合苹果 iOS 7.X 至 iOS 8.X 每个架构最大为 60 MB 的要求!
具体的代码,可参考我的Github代码:
calculate_Mach-0__Text-Size .sh
:
#!/bin/bash # 定义用到的变量 ExecutableFilePath="" # 定义读取输入字符的函数 getExecutableFilePath() { # 输出换行,方便查看 echo "================================================" # 监听输入并且赋值给变量 read -p " Enter Mach-O executable file path: " ExecutableFilePath # 如果为空值,从新监听 if test -z "$ExecutableFilePath"; then echo "Error! Should enter file path " getExecutableFilePath fi } getExecutableFilePath echo "Place enter the number select minimum supported system version for the app? [ 1:gt iOS9 2:lt iOS7 3:iOS7.X~8.X] " read number while([[ $number != 1 ]] && [[ $number != 2 ]] && [[ $number != 3 ]]) do echo "Error! Should enter 1 or 2 or 3" echo "Place enter the number you want to export ? [ 1:app-store 2:ad-hoc 3:dev] " read number done if [ $number != 3 ];then app_size=$(echo `size ${ExecutableFilePath} | awk '{print $1}' | grep -E '[0-9]' | awk '{sum += $1}; END {print sum/1000/1000}'`) echo 'executable file size:' ${app_size} 'MB' if [ $number == 1 ];then #iOS 9.0 或更高版本 500 MB 针对二进制文件中所有“__TEXT”部分的总和。 #因为bc和awk都支持浮点数,可以使用bc进行处理: if [ `echo "$app_size > 500" | bc` -eq 1 ];then echo ' [Error]' ${app_size} 'MB,' '不符合苹果 iOS9 小于 500 MB 的要求!' else echo '⭕️ [Success]' ${app_size} 'MB,' '符合苹果 iOS9 小于 500 MB 的要求!' fi else #低于 iOS 7.0 80 MB 针对二进制文件中所有“__TEXT”部分的总和。 if [ `echo "$app_size > 80" | bc` -eq 1 ];then echo ' [Error]' ${app_size} 'MB,' '不符合苹果 iOS7 小于 80 MB 的要求!' else echo '⭕️ [Success]' ${app_size} 'MB,' '符合苹果 iOS7 小于 80 MB 的要求!' fi fi else app_size=$(echo `size "$ExecutableFilePath" | awk '{print $1 "," $10}' | tail -n +2`) # iOS 7.X 至 iOS 8.X 每个架构最大为 60 MB # echo $app_size # 53329920,armv7) 57475072,arm64) arch_arr=(`echo $app_size | tr ' ' ' '`) for each in ${arch_arr[@]} do size=`echo $each | awk -F',' '{print $1}' | awk '{sum += $1}; END {print sum/1000/1000}'` arch=`echo $each | awk -F',' '{print $2}'` # echo ${arch/%)/} # 如果字符串arch以)结尾,则用空替换它 echo ${arch/%)/} 'executable file size:' ${size} 'MB' if [ `echo "$size > 60" | bc` -eq 1 ];then echo ' [Error]' ${arch/%)/} 'size:' ${size} 'MB,' '不符合苹果 iOS 7.X 至 iOS 8.X 每个架构最大为 60 MB 的要求!' else echo '⭕️ [Success]' ${arch/%)/} 'size:' ${size} 'MB,' '符合苹果 iOS 7.X 至 iOS 8.X 每个架构最大为 60 MB 的要求!' fi done fi
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,如若转载,请注来源
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
PHP技术月刊第2期:直面PHP微服务架构挑战
【点击订阅PHP技术月刊】 云栖社区“世界上最好的编程语言”——PHP开始发布技术月刊啦。PHP技术月刊将会为大家介绍最新的PHP技术与动态、预告活动、最热问答以及技术直播等,欢迎大家订阅。 最新动态 阿里云栖开发者沙龙PHP技术专场-直面PHP微服务架构挑战在4月20日的阿里云栖开发者沙龙PHP技术专场上,云智慧Technical VP高驰涛为大家介绍了微服务的前世今生,分享了微服务架构实践中所面对的诸多挑战以及相应的应对策略。 阿里云栖开发者沙龙PHP技术专场-深入浅出网络编程与Swoole内核在阿里云PHP技术沙龙专场中,阿里云邀请到php-nsq作者,pecl、Swoole开发组成员吴振宇分享了Swoole进程模型的原理与Swoole协程实现的原理。并结合具体开发案例讲解了Swoole在网络编程中的应用。 阿里云栖开发者沙龙PHP技
- 下一篇
突破Java面试(23)-如何保证redis高并发及高可用
1 面试题 如何保证Redis的高并发和高可用?redis的主从复制原理能介绍一下么?redis的哨兵原理能介绍一下么? 2 考点分析 其实问这个问题,主要是考考你,redis单机能承载多高并发?如果单机扛不住如何扩容抗更多的并发?redis会不会挂?既然redis会挂那怎么保证redis是高可用的? 其实针对的都是项目中你肯定要考虑的一些问题,如果你没考虑过,那确实你对生产系统中的问题思考太少。 3 详解 就是如果你用Redis缓存技术的话,肯定要考虑如何用redis来加多台机器,保证redis是高并发的,还有就是如何让Redis保证自己不是挂掉以后就直接死掉了 3.1 redis高并发 主从架构,一主多从,一般来说,很多项目其实就足够了,单主用来写入数据,单机几万QPS,多从用来查询数据,多个从实例可以提供每秒10万的QPS。 redis高并发
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS关闭SELinux安全模块
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Red5直播服务器,属于Java语言的直播服务器
- Hadoop3单机部署,实现最简伪集群