如何在使用多个框架子项目时使用CocoaPods

32

首先,在 Podfile 中我已开启了 use_framework!。

假设主项目为 MAIN_APP,另外有两个子项目 FRAMEWORK_A 和 FRAMEWORK_B。

MAIN_APP 需要 FRAMEWORK_A 和 FRAMEWORK_B,而 FRAMEWORK_B 也需要 FRAMEWORK_A。

所有项目/目标都使用 CocoaPods 管理第三方库。

现在,我的 Podfile 如下:

target :MAIN_APP do
    project 'MAIN_APP'
    pod 'PodA'
end

target :FRAMEWORK_A do
    project 'FRAMEWORK_A'
    pod 'PodB'
end

target :FRAMEWORK_B do
    project 'FRAMEWORK_B'
    pod 'PodC'
end
我在FRAMEWORK_B的构建设置中手动添加了FRAMEWORK_A,同时在MAIN_APP的构建设置中也添加了FRAMEWORK_A和FRAMEWORK_B。代码编译没有问题,但当运行MAIN_APP时会崩溃,因为它无法加载PodB框架。我知道可以手动将PodB添加到MAIN_APP和FRAMEWORK_B中,但是否可能在Podfile中定义这种目标依赖关系呢?顺便提一下,运行pod install时,我收到了以下警告:
[!] Podfile包含框架目标,而Podfile不包含主机目标(嵌入框架的目标)。如果此项目用于框架开发,则可以忽略此消息。否则,请向Podfile中添加一个嵌入这些框架的目标,以使此消息消失(例如测试目标)。
据我所知,我可以像这样使用嵌套目标来作为主机目标:
target :FRAMEWORK_A
    target :MAIN_APP
    end
end

因此,CocoaPods将设置 MAIN_APP 使用 FRAMEWORK_A 并继承来自 FRAMEWORK_A 的依赖项。但是似乎我无法使用多个依赖项实现这一点,例如:

target :FRAMEWORK_A
    target :MAIN_APP
    end
end
target :FRAMEWORK_B
    target :MAIN_APP
    end
end

因为目标:MAIN_APP不能声明两次。

除了将pod依赖项定义为Podfile中的函数并在所有目标中包含之外,还有更好的解决方案吗?


有进展吗?你解决了吗? - zaxy78
@zaxy78 我把它分成了不同的子项目,而不是不同的目标,因为我发现如果它们在一个项目中,尽管它们被添加到不同的目标中,你可以使用 "Header.h" 导入头文件,但我想强制使用 <Header.h> 从框架中导入头文件。 - Allen Hsu
我们有一个类似的结构,当我迁移到最新版本的XCode和CocoaPods时,它引起了一些奇怪的问题。目前正在尝试调试如何最好地管理这种类型的podfile。 - pixelknitter
需要提到的一件重要的事情是,当我将Pods.framework拖到主项目中时,它似乎是使用绝对路径引用的,因此我将其更新为相对路径到BUILT_PRODUCTS_DIR,然后对于不同的目标,它会编译正确版本的Pods框架。 - Allen Hsu
3个回答

7

这是一个非常好的问题,我曾经也和你面临类似的情况。这是我的PodFile:

platform :ios, '8.0'

workspace 'mygreatapp.xcworkspace'

project 'app/MyGreatApp/MyGreatApp.xcodeproj'
project 'platform/MyGreatFramework/MyGreatFramework.xcodeproj'

abstract_target 'This can say whatever you want' do

    target 'MyGreatApp' do
        project 'app/MyGreatApp/MyGreatApp.xcodeproj'
        pod 'AFNetworking', '~> 2.6.0'
        pod 'PromiseKit', '~> 1.5'
        pod 'PromiseKit/Join'
        pod 'KVOController', '~> 1.0'
        pod 'FLAnimatedImage', '~> 1.0'
        pod 'Crashlytics', '~> 3.3'
        pod 'SSZipArchive'
    end

    target 'MyGreatAppTests' do
        project 'app/MyGreatApp/MyGreatApp.xcodeproj'
        pod 'OCMock', '~> 3.1'
    end

    target 'MyGreatFramework' do
        project 'platform/MyGreatFramework/MyGreatFramework.xcodeproj'
        pod 'SSZipArchive'
    end

    target 'MyGreatFrameworkTests' do
        project 'platform/MyGreatFramework/MyGreatFramework.xcodeproj'
        pod 'OCMock', '~> 3.1'
    end

    post_install do |installer|
      installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
          config.build_settings['ENABLE_BITCODE'] = 'NO'
        end
      end
    end
end

正如您所看到的,我没有使用框架,而是使用abstract_target将所有内容分组在一起。我希望这种依赖关系在CocoaPods中更容易实现。我知道这并没有真正回答您的问题,但这可能仍然有所帮助。


2
我不确定这是否是一个真正的答案,还是只是另一个示例Podfile? - iwasrobbed
2
我的 Podfile 和你的一样。问题是,当 target 'MyGreatFramework' do pod 'Crashlytics' 时,我在应用启动时会收到警告:objc[15419]: Class xxx is implemented in both app and framework, One of the two will be used. Which one is undefined。你有解决方法吗? - jiangjiefs
这可能不是对所有阅读此文的人都显而易见的(如果一个人只做过简单的Pod安装)。但诀窍是将您的Podfile放在包含您的项目和子项目的父目录中。一旦我意识到了这一点,上述解决方案对我起作用了。 - Mario

6
我认为您也可以通过将 FrameworkAFrameworkB 转化为本地(静态库)pods 来解决这个问题,它会为您去重一切并正确地集成到主机应用程序中。
示例:https://github.com/rob-keepsafe/PodFrameworksIssue
  • master 分支显示了类的重复以及像您一样的 umbrella frameworks。
  • deduped 分支将内部动态框架转化为本地 pods(作为静态库)以去重,并仍然链接依赖性。

1
感谢您为我在两个项目中提供的唯一解决方案,愿上帝保佑您。 - Nikaaner
很高兴能帮到你,@Nikaaner! - iwasrobbed

1

我不确定你的问题是否与我的完全相同,但我将在此留下我的解决方案,以防有人遇到类似的问题。

我有一个项目,其中包含多个子项目,我使用这些子项目来模块化我的代码(并潜在地准备提取到自己的私有pod中)。 我遇到了一个问题,即一个子项目导入外部pod,并由于“缺少图像”而收到dyld错误。

我发现了这篇Medium文章,从中得出结论,我必须始终将pods包含在主项目中,以便子项目能够找到它们。我的两个外部pods都没有在主项目中使用。 ( https://medium.com/@akfreas/how-to-use-cocoapods-with-your-internal-ios-frameworks-192aa472f64b) (我可能没有像我应该那样正确或高效地编写podfile,但这似乎解决了我的问题)

因此,我的podfile如下:

abstract_target "RandomName" do

    target "MainProject" do
        inherit! :complete
        workspace './MainProject.xcodeproj'
        pod 'Moya', '~> 13.0'
        pod 'KeychainSwift', '~> 17.0'
    end

    target "ModuleA" do
      project './ModuleA/ModuleA.xcodeproj'
      workspace './ModuleA/ModuleA.xcodeproj'
      pod 'Moya', '~> 13.0'
    end

    target "ModuleB" do
      project './ModuleB/ModuleB.xcodeproj'
      workspace './ModuleB/ModuleB.xcodeproj'
      pod 'KeychainSwift', '~> 17.0'
    end
end

每当我设置使用CocoaPods的项目时,我总是回到这篇文章。 - nayooti

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