项目做多了之后,很容易遇到一个问题:同一套代码体系衍生多个 App,但提交 App Store 时被判定为重复应用(Guideline 4.3)。
我之前维护过一组工具类应用,功能框架一致,只是在内容和 UI 上做区分。第一次提交时,有几个版本直接被拒,原因很明确:结构相似度过高。
后来我们没有“文案包装入手,而是把重点放在应用结构、资源特征和二进制层差异上,重新梳理了一套流程。
一、先确认“相似”到底体现在哪
收到拒审后,不要急着改 UI,可以先从 IPA 层检查。
解包 IPA:
unzip app.ipa
进入:
Payload/App.app
重点看三类内容:
1. 可执行文件
strings AppBinary | grep Manager
如果不同 App 输出:
UserManager
OrderManager
VipService
完全一致,这一层已经形成结构指纹。
2. 资源目录
assets/images/home_banner.png
config/app_config.json
多个应用如果资源路径一致,也会被识别。
3. H5 / JS 内容
main.jsbundle
index.html
如果内容完全一致,只改 UI 是不够的。
二、功能差异之外,结构也要变
功能差异(比如增加模块、改交互)确实重要,但在技术层面,还需要让内部结构不再完全一致。
我们做了两类调整:
- 代码结构差异
- 资源结构差异
这两部分是在不改变业务逻辑的前提下完成的。
三、对二进制符号做差异处理
源码阶段如果不动,可以在 IPA 层处理。
使用 Ipa Guard 加载 IPA 后,可以看到:
OC 类
Swift 类
OC 方法
Swift 方法
在不同应用中,我们做了不同策略的混淆:
例如:
App A:
UserManager → a82kd3
App B:
UserManager → x92ls1
同一个类,在不同包中映射为不同名称。
这样处理后,即使功能一致,二进制结构已经不同。
四、资源路径重构(比 UI 更关键)
很多人只改 UI 图片,但忽略了路径结构。
例如:
assets/images/home_banner.png
如果所有应用都一样,依然容易被识别。
在 Ipa Guard 的资源模块中,可以:
- 批量改名
- 自动更新引用
处理后:
home_banner.png → a91ks.png
更进一步,我们在不同应用中使用不同策略:
- App A 使用短随机名
- App B 使用长随机名
让资源结构本身产生差异。
五、处理资源指纹(避免“同内容”识别)
如果资源内容完全一致,即使改名也可能被识别。
Ipa Guard 提供 MD5 修改能力:
处理前后不同。
这一步的效果是:
- 内容不变
- 指纹不同
六、前端资源也要参与差异化
如果应用中有 WebView 或 React Native 模块:
main.jsbundle
index.html
可以在构建阶段处理:
terser main.js -o main.min.js
不同应用使用不同压缩策略或变量名规则。
然后再用 Ipa Guard 修改文件名称。
清理调试信息(减少可比对内容)
调试信息也是特征之一。
检查:
strings AppBinary | grep NSLog
如果多个应用日志内容一致,也可能被识别。
在 Ipa Guard 中可以开启调试信息清理。
签名与安装测试
所有处理完成后,需要重新签名。
kxsign sign app.ipa \
-c cert.p12 \
-p password \
-m dev.mobileprovision \
-z test.ipa \
-i
测试时关注:
- 页面是否正常
- 功能是否受影响
- 资源是否加载
App Store 的审核不只是看功能,还会关注应用之间的相似性。功能差异是一部分,代码结构和资源特征同样重要。