AlipaySDK 与 Mpaas-Scan 冲突导致 iOS 打包失败
结论
问题来自两个静态库中重复的 UTDID 实现:
AlipaySDK.framework已经包含UTDIDPersistentFile等 UTDID 类。Mpaas-Scan又引入了独立的UTDID.framework。- 链接器生成 arm64 程序时检测到同名 Objective-C 符号,因此报出
duplicate symbol。
最终参与链接的 UTDID 实现只能有一份。
由于通常无法直接修改 AlipaySDK.framework,建议优先更换与当前 AlipaySDK 兼容且不携带独立 UTDID.framework 的 Mpaas-Scan 插件包。如果已经确认 Mpaas-Scan 可以复用 AlipaySDK 内置的 UTDID,也可以删除插件中的 UTDID.framework,同时移除插件配置里的相关引用。
冲突原因
报错中的两个路径已经指明了重复符号的来源:
AlipaySDK.framework/AlipaySDK
UTDID.framework/UTDID(UTDIDPersistentFile.o)
_OBJC_METACLASS_$_UTDIDPersistentFile 是 Objective-C 类的元类符号。两个静态二进制实现了同一个类,链接器无法决定保留哪一份,只能终止打包。
这个问题与架构缺失、证书异常或普通的 Framework Search Paths 配置无关。修改签名、Build Settings 或重新安装证书都无法解决。
推荐解决方案
方案一:更换兼容的 Mpaas-Scan 插件包
这种方式风险较低。
联系插件提供方,确认以下信息:
- 插件是否支持当前使用的 AlipaySDK 版本。
- 是否有不内置
UTDID.framework的版本。 - 是否提供经过统一依赖版本验证的 AlipaySDK、mPaaS Scan 和 UTDID 组合。
使用提供方验证过的依赖组合,可以减少打包成功后出现扫码初始化失败或运行时类冲突的风险。
方案二:从 Mpaas-Scan 中移除重复的 UTDID.framework
确认 Mpaas-Scan 能够复用 AlipaySDK 中的 UTDID 实现后,可以这样处理:
- 找到 Mpaas-Scan 原生插件的 iOS 目录。
- 删除其中的
UTDID.framework。 - 检查插件描述文件,从 iOS Framework 依赖列表中移除
UTDID.framework。 - 清理原生打包缓存。
- 重新生成并打包 iOS 工程。
调整前的目录结构可能类似:
nativeplugins/
└── Mpaas-Scan/
└── ios/
├── MpaasScan.framework
├── UTDID.framework
└── ...
调整后,目录中不应再有独立的 UTDID:
nativeplugins/
└── Mpaas-Scan/
└── ios/
├── MpaasScan.framework
└── ...
如果插件配置中有类似下面的声明,也要删除对应项。具体字段名称以插件实际使用的配置格式为准:
{
"frameworks": [
"MpaasScan.framework",
"UTDID.framework"
]
}
调整为:
{
"frameworks": [
"MpaasScan.framework"
]
}
不能只删除文件而保留配置引用,否则打包时可能会出现“找不到 UTDID.framework”的错误。
在 Xcode 工程中检查残留引用
使用离线打包工程时,还要检查以下位置:
- Target → General → Frameworks, Libraries, and Embedded Content
- Target → Build Phases → Link Binary With Libraries
- Target → Build Settings → Other Linker Flags
- Framework Search Paths
- CocoaPods、Podfile 或其他依赖管理配置
确认没有其他组件再次引入 UTDID.framework。
可以用下面的命令检查二进制中是否包含相关符号:
nm -gU AlipaySDK.framework/AlipaySDK | grep UTDIDPersistentFile
nm -gU UTDID.framework/UTDID | grep UTDIDPersistentFile
如果两条命令都能查到相同的 Objective-C 类符号,就可以确认重复实现来自这两个二进制。
修改完成后,先清理构建产物,再重新打包:
rm -rf ~/Library/Developer/Xcode/DerivedData/*
在 Xcode 中也可以使用:
Product → Clean Build Folder
如果通过云端或 uni-app 原生插件打包,还要清理对应平台的打包缓存,防止继续使用旧的 UTDID.framework。
不建议采用的处理方式
以下做法无法从根本上解决问题:
- 添加或删除
-ObjC - 使用
-all_load或-force_load - 忽略 linker error
- 随意删除 AlipaySDK 内部的目标文件
- 手工修改或重签 AlipaySDK 二进制
- 仅将
UTDID.framework设置为不嵌入,但仍让它参与链接
Do Not Embed 只控制 Framework 是否复制到 App 中,并不会阻止它参与链接。只要两份 UTDID 实现同时进入链接阶段,重复符号仍会出现。
注意事项
移除 Mpaas-Scan 自带的 UTDID.framework 后,至少要验证以下功能:
- 支付宝支付能否正常拉起并回调。
- 扫码组件能否正常初始化。
- 真机 arm64 环境下扫码是否正常。
- 冷启动和重复启动时是否出现 UTDID 相关崩溃。
- 控制台是否出现
Class ... is implemented in both ...警告。 - Release 和 Archive 构建是否都能通过。
如果删除独立 UTDID 后出现 Undefined symbols、Class not found 或扫码初始化失败,说明当前 Mpaas-Scan 无法直接复用 AlipaySDK 内置的实现。此时不要再通过链接参数强行处理,应更换兼容的插件版本,或让插件提供方重新编译 Mpaas-Scan,确保整个项目只依赖一套 UTDID。
备注:内容仅供参考。
