Class X 在 <framework> 和 <application> 中都实现了,将使用两者之一,未定义

Class X is implemented in both <framework> and <application> one of the two will be used, which one is undefined

我收到此警告:

Class X is implemented in both <framework> and <application> one of the two will be used, which one is undefined

这个警告在整个网络上都有很多报道,但我还没有找到任何可以回答我遇到的具体问题的东西。

场景

我已经构建了 MyFramework 和 MyApplication(作为 MyFramework 的 test/demo 应用程序)。

MyFramework 使用 CocoaPod(我将其称为 CoolPod),我也想在 MyApplication 中使用它(假设 MyFramework 的消费者也会这样做是合理的)。

我需要能够将 MyFramework 作为 .framework(对于闭源)进行分发。但是,这意味着 MyFramework 在其编译库中嵌入了 CoolPod。

现在,当我将 MyFramework 和 CoolPod 导入 MyApplication 时,我遇到了这个冲突(输出上面显示的警告),因为 CoolPod 的 类 已经包含在 MyFramework 的库中(因为嵌入了 CoolPod)。

所以我们有这样的结构:

CoolPod -> MyFramework \
                        MyApplication
               CoolPod /

问题

如何避免这种冲突?

我考虑过在 MyApplication 中包含 CoolPod 的 headers(但不是它的库),但是对于一个简单的案例来说这似乎过于复杂。

非常感谢任何帮助,这真的让我很困扰。

谢谢,

靛蓝

对于闭源静态库,我们推荐 cocoapods-packager。不过我不确定它是否支持框架。

我的解决方案是从 cocoa pod 中获取源代码并为其创建一个 Cocoa Touch Framework。然后我将该框架链接到我的 api 和我的测试应用程序。 这不是很好,但这是我能很快做的。我相信 Cocoapods 正在研究支持框架,所以这个解决方案可能很快就会过时。

我的公司还使用 gradle 作为依赖项 (java) 和构建脚本。所以我创建了一个 groovy/gradle 构建任务来构建我的框架和我的支持框架(cocoapod 框架)并从中创建一个通用框架。然后它压缩所有的框架。这意味着我可以分发一个包含所有要求的 zip。这显然不是最好的分发方式(我们将转向通过 Cocoapods 分发,依赖于我们的闭源框架),但它设置起来很快。

一种解决方法是开启use_frameworks!在框架的 Podfile 中。然后你仍然可以编译你的框架,并将你的框架嵌入到目标应用程序中。警告消息将消失(这只是因为框架的 pods 符合另一个框架,但你没有将这个框架嵌入到你的目标应用程序中。然后你的应用程序将引用它自己的二进制文件。)

但这不是一个好的解决方案,原因有二: 1.您需要确保目标应用程序包含框架所需的必要pods。 2. 应用程序可能使用与框架不同的 pod 版本。如果框架和应用程序都引用同一个 pod 二进制文件,则可能会导致崩溃。

我怀疑这个问题是否有好的解决方案。

如果您想要快速解决方案 - 只需将您的 MyFramework 项目作为子项目添加到 MyApplication 项目中。您仍然可以将 cocoa pods 用于您的框架和测试应用程序(但仅将您的 "common" 库与 pods 包含在框架项目中)

您可以为您的 MyFramework 创建一个 Podspec,并将 CoolPod 作为依赖项。


您的 MyFramework.podspec 将类似于:

Pod::Spec.new do |spec|
  spec.name          = 'TestFW'
  spec.version       = '1.0.0'
  spec.license       = { :type => 'BSD' }
  spec.homepage      = 'https://github.com/user/TestFW'
  spec.authors       = { 'Auther Name' => 'author@gmail.com' }
  spec.summary       = 'Testing FW Pod with Test App'
  spec.source        = { :git => 'https://github.com/user/TestFW.git' }
  spec.module_name   = 'TestFW'
  spec.ios.source_files   = 'TestFW/*.swift'

  spec.dependency 'CoolPod'
end

你的 MyApplicationpodfile 看起来像这样:

target 'TestApp' do
  use_frameworks!

  pod 'CoolPod'
  pod 'TestFW'
end