类X在<framework>和<application>中都被实现,其中之一将被使用,但到底使用哪个是不确定的。

49

我收到了这个警告:

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

这个警告在网上已经被广泛讨论,但我没有找到任何解决我正在遇到问题的具体方法。

场景

我已经构建了MyFramework和MyApplication(作为MyFramework的测试/演示应用程序)。

MyFramework使用了一个CocoaPod(我将其称为CoolPod),我也想在MyApplication中使用它(假设MyFramework的消费者也会用到它)。

我需要以.framework形式分发MyFramework(作为闭源)。然而,这意味着MyFramework将CoolPod嵌入其编译库中。

当我将MyFramework和CoolPod导入到MyApplication中时,我会得到这个冲突(输出如上所示的警告),因为CoolPod的类已经包含在MyFramework的库中(因为CoolPod被嵌入其中)。

所以我们有这个结构:

CoolPod -> MyFramework \
                        MyApplication
               CoolPod /

问题

我该如何避免这个冲突?

  • 是否有一种方法让我的应用程序提供CoolPod给MyFramework?
  • 我是否必须通过MyFramework传输CoolPod的头文件?

我考虑过在MyApplication中包含CoolPod的头文件(但不是库文件),但对于本应该是简单情况而言,这似乎过于复杂。

非常感谢任何帮助,这真的阻碍了我。

谢谢,

Indigo


3
我有类似的问题,你找到解决方法了吗? - cocoapriest
1
类似的问题,但是涉及单元测试,可以在这里讨论:https://dev59.com/qW025IYBdhLWcg3wNTAV - ThomasW
1
令人惊讶的是,这不是一个非常常见的模式吗?开发人员不想创建编译单元的DAG而不必担心会发生冲突吗?! - fatuhoku
1
嗨@Zenton。除了被接受的答案,你是否用不同的解决方案解决了这个问题?我也遇到了同样的问题,非常感谢你的建议。 - Fernando Reynoso
@FernandoReynoso 你找到解决方案了吗?谢谢 - undefined
5个回答

3
我的解决方案是从Cocoapod获取源代码并创建一个Cocoa Touch框架。然后将该框架链接到我的API和测试应用程序中。 这不是很好,但这是我能够快速完成的所有工作。我相信Cocoapods正在努力支持框架,因此这种解决方案可能会很快过时。
我公司还使用gradle进行依赖项(Java)和构建脚本。因此,我创建了一个Groovy / Gradle构建任务,用于构建我的框架和支持框架(Cocoapod框架),并从中创建通用框架。然后将所有框架打包成zip。这意味着我可以分发一个带有所有要求的zip文件。显然,这不是最好的分发方式(我们将转而通过Cocoapods分发,并依赖于我们的闭源框架),但它可以快速设置。

2

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


1
一种解决方案是在框架的Podfile中启用use_frameworks!。然后,您仍然可以使您的框架编译,并将您的框架嵌入目标应用程序中。警告消息将消失(这仅是因为框架的pods被编译到另一个框架中,但您没有将其嵌入到目标应用程序中。然后,您的应用程序将引用其自身的二进制文件。)
但是,这不是一个好的解决方案,原因有两个: 1. 您需要确保目标应用程序包含框架所需的必要pods。 2. 应用程序可能使用与框架不同的pod版本。如果框架和应用程序都引用相同的pod二进制文件,则可能导致崩溃。
我怀疑这个问题没有好的解决方案。

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

我无法使这种方法起作用 - 应用程序目标无法链接,对于仅包含在框架中的Pods中定义的任何类,都会出现“找不到arm64体系结构的符号”。有什么想法吗? - stephent
这对我起作用了。我只需要删除我的派生数据就可以让它工作了。 - Alpine

0
您可以使用CoolPod作为依赖项,为您的MyFramework创建Podspec

你的 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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接