如何解决主项目CocoaPod与Swift Package的SDWebImage依赖冲突
重复符号冲突解法
你遇到的警告是SDWebImage同时通过CocoaPods和Swift Package Manager(SPM)引入,导致同一个类的符号在两份二进制中都存在,运行时选择不明确产生的告警,两个问题的解法如下:
问题1解答
两种方案均可实现:
- 方案1:Podfile添加条件判断逻辑,检测到SPM已经引入SDWebImage时不引入Pod版本
可以读取主项目的SPM依赖解析文件判断是否已经存在SDWebImage,示例代码如下:
修改完成后重新执行# 替换成你自己的主项目xcodeproj文件名 project_path = "MyMainProject.xcodeproj" spm_resolved_path = "#{project_path}/project.xcworkspace/xcshareddata/swiftpm/Package.resolved" # 判断SPM是否已引入SDWebImage use_spm_sd = File.exist?(spm_resolved_path) && File.read(spm_resolved_path).include?("SDWebImage") target 'MyMainProject' do # 其他依赖保持不变 unless use_spm_sd pod 'SDWebImage', '~> 5.0' end endpod install即可。 - 方案2:直接移除主项目中SPM引入的SDWebImage
如果你优先使用CocoaPods版本的SDWebImage,只需要调整你的MyPacket包的配置即可,具体操作见问题2的解法。
问题2解答
可以实现,只需修改MyPacket的Package.swift配置和导入语句,让MyPacket不主动拉取SDWebImage依赖,运行时直接用宿主项目提供的版本即可:
- 修改MyPacket的
Package.swift,给target添加链接参数,让编译时不强制链接SDWebImage,运行时动态查找符号:// swift-tools-version:5.5 import PackageDescription let package = Package( name: "MyPacket", products: [ .library(name: "MyPacket", targets: ["MyPacket"]) ], // 可以删掉SDWebImage的全局依赖声明,也可以保留仅用于开发测试 dependencies: [], targets: [ .target( name: "MyPacket", dependencies: [], linkerSettings: [ .unsafeFlags(["-Xlinker", "-undefined", "-Xlinker", "dynamic_lookup"], .when(platforms: [.iOS])) ] ) ] ) - 所有MyPacket中导入SDWebImage的地方,添加
@_implementationOnly前缀:
该关键字会让SDWebImage的符号仅在MyPacket内部可见,不会暴露为公共接口,避免上层需要显式引入该依赖。@_implementationOnly import SDWebImage
注意:需要保证MyPacket兼容的SDWebImage版本和主项目CocoaPods引入的版本大版本号一致,否则可能出现运行时找不到方法的崩溃问题。
修改完成后重新将MyPacket引入主项目,主项目的SPM依赖列表就不会再自动拉取SDWebImage,MyPacket会直接调用CocoaPods引入的SDWebImage实现,重复告警会自动消失。
内容的提问来源于stack exchange,提问作者poPaTheGuru
相关产品推荐
相关产品推荐

