introduce
Share a script tool for analyzing iOS
ipa packages. Using this tool can 自动扫描发现
fix the package volume problem and generate package volume data for viewing. This tool has been used within our team for a long time, and we hope it can help more developers optimize package size issues more efficiently.
background
APPAnalyze
The tool was first born mainly to solve the following package volume management problems:
For those targeting lower-tier markets APP
, package size is a very important performance indicator. Excessive package size will affect users’ APP
willingness to download. But in the early days, we lacked some means to help us manage package volume more efficiently.
Automatically discover problems
-
提升效率
- Manual troubleshooting is inefficient. Common problems should be automatically scanned as much as possible. And for组件化
projects, many external components areFramework
provided through methods, and there is no warehouse source code permission to analyze package size issues. -
流程化
- Form an automated quality process and add toCI流水线
automatically detect package volume problems.
Quantification of data indicators
-
包体积问题
- Provide a data-based platform to view the package volume of each待修复
component -
包体积大小
- Provide a data-based platform to view the package volume proportion of each component, including总大小
individual files二进制大小
and each资源大小
.APP
Package volume data at component granularity can be compared for different versions, making it easier to view the component size increment of each version.
Method to realize
We chose to achieve this capability by not relying on source code but directly scanning binary libraries. The overall execution process is as follows:
Tip: The scanning method based on component engineering is supported internally, but it is not open to the public for the time being.
user's guidance
Install
No installation required. Directly download the terminal executable command file through the download link APPAnalyzeCommand
to your local computer for use.
APPAnalyzeCommand download address
use
$ /Users/Test/APPAnalyzeCommand --help
OPTIONS:
--version <version> 当前版本 1.0.0
--output <output> 输出文件目录。必传参数
--config <config> 配置JSON文件地址。非必传参数
--ipa <ipa> ipa.app文件地址。必传参数
-h, --help Show help information.
implement
Open the terminal program and directly execute the following shell
commands to generate ipa
the package volume data and package volume issues to be fixed.
Tip: If
AppStore
the package cannot be used directly,AppStore
the shell of the package needs to be smashed. It is recommended to use XCodeDebug
packages as much as possible.
/Users/Test/APPAnalyzeCommand --ipa ipas/JDAPP/JDAPP.app --output ipas/JDAPP
Tip: If you are prompted that
permission denied
you don’t have permission,sudo chmod -R 777 /Users/a/Desktop/ipas/APPAnalyzeCommand
just execute it.
Generate products
After the command is executed, a folder will ouput
be generated in the folder specified by the parameter . APPAnalyze
The specific documents are introduced as follows:
Packet volume information
app_size.html
- Displaysipa
eachframework
packet volume data and can be opened directly with a browser.
Tip: Divide the granularity according to the main program and dynamic library
framework_size.html
- Displayframework
all package volume data for a single package二级页面不要直接打开
.
Tip: When
XCode
generatingAssets.car
, some small pictures will be spliced into onePackedAssetImage
large picture.
package_size.json
-Packageipa
volume JSON data
Issues with package size to be fixed
app_issues.html
- Displays the number of issues to be fixed foripa
eachframework
package volume, which can be opened directly with a browser.
Tip: Divide the granularity according to the main program and dynamic library
framework_issues.html
- Displayframework
detailed data of all single issues to be fixed二级页面不要单独打开
.
issues.json
-JSONipa
data of package size issue to be fixed
Tip:
json
Data can be used to build your own data platform and expand more capabilities. For example, view different APP versions and support comparison of multiple APP versions.
Rule introduction
Packet volume
unused class
The defined class is not used, including ObjC
classes and Swift
classes.
Scan rules
-
The corresponding
ObjC
class was not found to be referenced. -
Not used as a parent class
-
Unused strings and class names are consistent
-
Not used as an attribute type
-
No method was created or called
-
There is no implementation
+load
method
Optional repair methods
-
Remove unused classes
-
Swift
If the class only usesstatic
methods, consider changing it toEnum
a type -
If it is only used during type conversion, it will also be detected as an unused class, for example
(ABCClass *)object;
. It is recommended to check whether there are really relevant classes and then delete them. -
For
ObjC
, if it is only used as a method parameter type, it will also be detected as an unused class. It is recommended to delete the relevant methods.
Tip: Deleting a class is relatively safe because a compile-time error will occur if it is used after deletion. Although there is scanning and filtering for string calls, it is still recommended to check whether it may be
Runtime
dynamically created and called.
Unused ObjC protocols
The protocol defined ObjC
is not used by the class
Scan rules
- The corresponding protocol is not referenced by the class
Optional repair methods
- Remove unused protocols
Multiple Scale pictures in Bundle
Bundle
Containing multiple images of the same image Scale
will result in a larger package size.
Scan rules
- There are different pictures
Bundle
with the same name in the same memory.scale
For example[email protected]
/[email protected]
Optional repair methods
- Remove
Scale
lower images
Great resources
If the file size exceeds a certain size, it is considered a large resource. The default is 20KB
.
Scan rules
- A certain file exceeds the set maximum resource limit
Optional repair methods
-
Remove dynamic delivery of resources
-
Use smaller data formats, such as smaller image formats
Duplicate resource files
There are multiple identical duplicate files.
Scan rules
- If multiple files
MD5
are consistent, they are deemed to be duplicate files.
Optional repair methods
- Remove redundant files
Unused class Property attribute
ObjC
Properties defined in the class are not used.
Scan rules
-
The corresponding attribute has not been called set/get method, and it has not been
_
used in the way -
Not a property from the implementation protocol
-
Not
Category
an attribute from -
There is no string usage consistent with the attribute name.
Optional repair methods
-
Remove the corresponding attribute
-
If it is an attribute of an interface protocol, you need to add a class to implement this interface
注意事项
- There may be some dynamic usage scenarios that require certain checks. For example, in some inherited
NSObject
data model classes, there may be properties that are not used directly, but may be calledJSON
as parameters. For example, the data model issued by the background
Unused ImageSet/DataSet
The included Imageset
/ DataSet
is not used.
Scan rules
Imageset
No string usage with the same name detected
Optional repair methods
- Remove ImageSet/DataSet
注意事项
-
Swift
Strings used in some code cannot be found and are treated as unused. -
Use the name of string concatenation as the name of the imageset.
-
PackedAssetImage
What is synthesizedImageset
cannot be scanned out.
Unused ObjC method
The defined ObjC
Category method is not used.
Scan rules
-
There is no method name identical to this method.
-
字符串
There is no consistent method name used. -
Category
Method not from parent class or -
Not from a method that implements an interface
-
Not an attribute set/get method
Optional repair methods
- Remove the corresponding method
Unused classification method
The defined ObjC
Category method is not used.
Scan rules
-
There is no method name identical to this method.
-
There is no consistent
字符串
use with the method name -
Category
Method not from parent class or -
Not from a method that implements an interface
Optional repair methods
-
Remove unused methods
-
If it is a method of an interface protocol, you need to add a class to implement this interface
unused resource files
The included file resources are not used. The resource here does not contain Imageset
/ DataSet
.
Scan rules
- No string usage with the same name as the file name was detected.
Optional repair methods
- Remove resources
注意事项
-
Strings used in some
Swift
code cannot be found and are treated as unused -
Use string concatenation as the name of the resource
Safety
Dynamic reflection call ObjC class
If the class name is consistent with the string, it is possible to use NSClassFromString()
methods to dynamically call the class. When 字符串
or when the class name is changed, compile-time checking cannot be used to detect problems, which may lead to functional abnormalities.
Scan rules
- Existence uses the same name
字符串
as the classNSObject子类
Optional repair methods
-
Use
NSStringFromClass()
to get the class name string -
When using
Framework
external classes, you should use method encapsulation. Except for a few functions, reflection should not be used to call them.类
Tip: Include inherited
NSObject
swift classes.
ObjC property memory declaration error
Some special NSObject
types of attribute memory type declaration errors may cause functional abnormalities or triggers Crash
.
Scan rules
-
NSArray
// Type attribute usageNSSet
declarationNSDictionary
strong
-
NSMutableArray
// Type attribute usageNSMutableSet
declarationNSMutableDictionary
copy
Optional repair methods
- Modify
strong
/copy
state
Conflict Classification Methods
ObjC
Category
There are multiple identical methods in multiple categories of the same class . Since the final method loaded at runtime may be uncertain, it may lead to unknown behaviors such as functional abnormalities.
Scan rules
NSObject类
Category
There are multiple identical methods in multiple categories of
How to fix it
- Remove redundant classification methods
Duplicate classification method
ObjC
The original class and Category
the classification of the class have the same methods. The methods in the classification will overwrite the methods of the original class, which may lead to unknown behaviors such as functional abnormalities.
Scan rules
NSObject
Category
There are the same methods in the original class and the classification of the class
How to fix it
- Remove duplicate classification methods
Unimplemented ObjC protocol method
The class implements a certain ObjC
protocol, but has no 非可选
methods that implement the protocol. May cause malfunction or triggering Crash
.
Scan rules
类
and methods分类
that do not implementNSObject
the protocol非可选
Optional repair methods
-
The corresponding class implements the missing
非可选
protocol method -
Mark the corresponding protocol method as
optional
an optional method
Duplicate ObjC classes
The same exists between multiple 动态库
and . It will not cause compilation failure, but only one of the classes will be used at runtime, which may cause functional abnormalities or triggers . will increase at the same time .静态库
类
Crash
包体积
Scan rules
- The same symbol exists between multiple
动态库
and静态库
NSObject类
Possible fixes
- Remove duplicate classes
performance
Use dynamic libraries
Using dynamic libraries will increase 启动
time consumption.
Scan rules
Macho
for dynamic library
Optional repair methods
-
use
静态库
-
use
Mergeable Library
The class that implements +load
the method
启动
All +load
methods will be executed after the APP . Reducing +load
methods can reduce startup time.
Scan rules
- The class that implements
+load
the methodNSObject
Optional repair methods
-
Removal
+load
method -
Use
+initialize
alternative
Custom configuration
Important configuration
systemFrameworkPaths
You can configure the system library directory based on your own project, and the system library will also be parsed when parsing the project. Configuring the system library directory to search for unused methods can provide more information to avoid false positives. However, configuring more will result in slower execution. It is recommended to configure at least Foundation
/ UIKit
.
unusedObjCProperty-enable
unusedObjCProperty
Rules are not enabled by default.
- After turning on the unused attribute check, the segments will be scanned
macho
,__TEXT
which will increase the time of analysis.
unusedClass-swiftEnable
unusedClass-swiftEnable
Not enabled by default.
-
After turning on
Swift
class checking, the segments will be scannedmacho
,__TEXT
which will increase the time of analysis. -
It is recommended not to open projects with unused
Swift
classes. If execution performance is considered,Swift
use relatively many classes before opening them.
Tip: The scanned
macho
segments__TEXT
need to useXCode
the package compiled by Run, and cannot directly useAPP Store
the package built for the shelf. MainlyDebug
it will contain more information for scanning.
Configuration properties
/Users/Test/APPAnalyzeCommand -ipa /Users/Desktop/ipas/APPMobile/APPMobile.app -config /Users/Desktop/ipas/config.json --output /Users/Desktop/ipas/APPMobile
You can add the following rule configurable parameters based on your own project needs. APPAnalyzeCommand
Add the configuration file address when using the directive --config
.
{
"systemFrameworkPaths": ["/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore", "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation",
"/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/Foundation.framework/Foundation"
], // 配置系统库。会极大增加未使用方法的误报
"rules": {
"dynamicCallObjCClass": { // 动态调`ObjC类
"enable": false, // 是否启用
"excludeClasslist": [ // 过滤类名
"NSObject",
"param"
]
},
"incorrectObjCPropertyDefine": { // 错误的 ObjC 属性定义
"enable": false // 是否启动
},
"largeResource": { // 大资源
"maxSize": 20480 // 配置大资源判定大小。默认 20480Byte=20KB
},
"unusedObjCProperty": { // 未使用的 ObjC 属性
"enable": false, // 是否启用。默认不开启
"excludeTypes": ["NSString", "NSArray", "NSDictionary", "NSNumber", "NSMutableArray", "NSMutableDictionary", "NSSet"] // 过滤掉部分类型的属性
},
"unusedClass": { // 未使用的类
"swiftEnable": false, // 是否支持 Swift 类。默认不支持
"excludeSuperClasslist": ["JDProtocolHandler", "JDProtocolScheme"],// 如果类继承了某些类就过滤
"excludeProtocols": ["RCTBridgeModule"], // 如果类实现了某些协议就过滤
"excludeClassRegex": ["^jd.*Module$", "^PodsDummy_", "^pg.*Module$", "^SF.*Module$"] // 过滤掉名字符合正则表达式的类
},
"unusedObjCMethod": { // 未使用的 ObjC 方法
"excludeInstanceMethods": [""], // 过滤掉某些名字的对象方法
"excludeClassMethods": [""], // 过滤掉某些名字的类方法
"excludeInstanceMethodRegex": ["^jumpHandle_"], // 过滤掉名字符合正则表达式的对象方法
"excludeClassMethodRegex": ["^routerHandle_"], // 过滤掉名字符合正则表达式的类方法
"excludeProtocols": ["RCTBridgeModule"] // 如果类集成了某些协议就不再检查,例如 RN 方法
},
"loadObjCClass": { // 调用 ObjC + load 方法
"excludeSuperClasslist": ["ProtocolHandler"], // 如果类继承了某些类就过滤
"excludeProtocols": ["RCTBridgeModule"] // 如果类实现了某些协议就过滤,例如 RN 方法
},
"unusedImageset": { // 未使用 imageset
"excludeNameRegex": [""] // 过滤掉名字符合正则表达式的imageset
},
"unusedResource": { // 未使用资源
"excludeNameRegex": [""] // 过滤掉名字符合正则表达式的资源
}
}
}
Component engineering scanning
APPAnalyzeCore.framework
You can implement your own componentized project scanning based on customization, or add inspection rules based on your own componentized project. Details can be seen Demo
.
The component-based scanning method has the following advantages:
-
细化数据粒度
- The package volume and package volume issues of each module can be refined, making it easier to optimize package volume. -
更多的检查
- For example, check that different components contain the same file with the same name, and different components contain the implementation ofBundle
the same method.category
-
检查结果更准确
- For example,ObjC
when checking for unused methods, as long as there is a call with the same name as the method, it means that the method is used. However,ipa
there may be many same method names in the entire process, but only one method is actually called. If you break down the component granularity, you can find more problems.
Tip: Only projects with no code in the main APP project and all
framework
binary libraries imported through sub-components are suitable for this mode.
other
How is the scan quality?
This set of tools has been developed internally by our team and gradually improved for a year. Based on this tool, the package size problem of dozens of components has been modified, and false positive problems have been continuously fixed. The false positive rate of these currently provided rule checks is very low. Only a few rules may have the possibility of false positives. The overall scanning quality is still very high.
What are the differences with community open source tools?
We investigated several open source tools of the same type in the community in the early days, and found the following main problems:
-
扩展性不够
- Unable to support better expanded customization capabilities of the project, such as adding scanning rules, supporting different types of scanning methods, and generating more report types. -
功能不全
- Only provide some capabilities, such as only未使用资源
or未使用类
. -
无法生成包体积数据
- Unable to generate data with complete package volume. -
检查质量不高
- The scan found a lot of erroneous data, or some problems could not be found.
Open source project
It will definitely be open sourced in the future. The main reason is that I hope to adjust some internal structures before open source. It will be inconvenient to adjust after open source. Fix some common problems by the way.
Benefits of open source
The benefit of open source is that some projects can expand and customize their own scanning tools based on their own business needs. At the same time, some better idea implementations can also be added.
-
扩展解析方式
- Currently onlyipa
pattern scanning is supported, andproject
scanning methods that support componentized projects will soon be opened. Based on组件化工程
scanning, it can be more accurate, but different companies组件化工程
may have different construction methods. If necessary, you can customize your own组件化工程
scanning analysis at the upper level. -
扩展扫描规则
- Although more general rules have been added, it also provides a certain degree of flexible configuration capabilities. However, different projects may need to customize some other rules, which cannot be implemented by adding configuration capabilities to existing rules. -
扩展数据生成
- The default package only contains two types of data generation,包体积
data and包体积待修复问题
data. More data generation formats can be expanded. For example, our own project adds a component-based dependency tree format.
Follow-up planning
Component engineering support
Add more scans for componentized engineering
Better support for Swift
For Swift
languages, as long as XCode
compilation optimization is turned on, the removal of useless code can be supported when generating products, including the automatic removal of 未使用类型
and 未使用方法
, but there are still some scenarios that will not be optimized. Therefore, this area is also the focus of subsequent improvement:
-
未使用属性
属性
- The compiler will not remove unused attributes , includingclass
and .struct
-
未使用方法
- Forclass
the method, the compiler will not remove it, even if it is not declared[@objc](https://my.oschina.net/TnhqVdFXL8vnu)
for message dispatch.
Related Links
OpenAI opens ChatGPT Voice Vite 5 for free to all users. It is officially released . Operator's magic operation: disconnecting the network in the background, deactivating broadband accounts, forcing users to change optical modems. Microsoft open source Terminal Chat programmers tampered with ETC balances and embezzled more than 2.6 million yuan a year. Used by the father of Redis Pure C language code implements the Telegram Bot framework. If you are an open source project maintainer, how far can you endure this kind of reply? Microsoft Copilot Web AI will be officially launched on December 1, supporting Chinese OpenAI. Former CEO and President Sam Altman & Greg Brockman joined Microsoft. Broadcom announced the successful acquisition of VMware.Author: JD Retail He Xiao
Source: JD Cloud Developer Community Please indicate the source when reprinting