How to use CocoaPods with multiple Framework subpr

2020-05-17 04:15发布

问题:

First of all, I've turned on use_framework! in Podfile.

Assume the main project is MAIN_APP, and two subprojects are FRAMEWORK_A and FRAMEWORK_B.

MAIN_APP requires FRAMEWORK_A and FRAMEWORK_B, and FRAMEWORK_B requires FRAMEWORK_A as well.

All projects/targets are using CocoaPods to manage third party libraries.

For now, my Podfile looks like:

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

I manually added FRAMEWORK_A to build settings of FRAMEWORK_B, and both FRAMEWORK_A and FRAMEWORK_B to build settings of MAIN_APP.

All code compiles well, but when running the MAIN_APP crashes because it cannot load Framework of PodB.

I know I can manually add PodB to MAIN_APP and FRAMEWORK_B as well, but is it possible to define this kind of target dependency in Podfile?

Btw, when pod install, I got the warning:

[!] The Podfile contains framework targets, for which the Podfile does not contain host targets (targets which embed the framework).

If this project is for doing framework development, you can ignore this message. Otherwise, add a target to the Podfile that embeds these frameworks to make this message go away (e.g. a test target).

As I know, I can use nested target for host targets like:

target :FRAMEWORK_A
    target :MAIN_APP
    end
end

So CocoaPods will setup MAIN_APP to use FRAMEWORK_A and inherit pod dependencies from FRAMEWORK_A. But seems I cannot do it with multiple dependencies like:

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

Because target :MAIN_APP cannot be declared twice.

Is there any better solutions instead of defining pod dependencies as a function in Podfile and include in all target?

回答1:

I think you can also get around this by just making FrameworkA and FrameworkB into local (static library) pods and it will de-duplicate everything for you and integrate it into the host app properly.

Examples: https://github.com/rob-keepsafe/PodFrameworksIssue

  • master branch shows duplicate classes and umbrella frameworks like you have
  • deduped branch makes the internal dynamic frameworks into local pods (as static libs) to de-dupe and still link in the dependencies


回答2:

This is a great question and I've struggled with a similar situation. This is my 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

As you can see I'm not using frameworks and I use an abstract_target to group it all together. I wish these kinds of dependencies were easier to do in CocoaPods. I know this doesn't really answer your question but it might be helpful nonetheless.



回答3:

I'm not entirely sure your issue is the same as mine, but I'm going to leave my solution here just-in-case someone has a similar issue.

I have a project with multiple sub-projects I use to modularize my code (and potentially prepare to extract to my own private pods). I had the issue of one importing an external pod to one of the sub-projects, and receiving a dyld error due to a "missing image".

I found this Medium article from which I concluded that I had to always include the pods in the main project for the sub-projects to be able to find them. Neither of my external pods are used in the main project. ( https://medium.com/@akfreas/how-to-use-cocoapods-with-your-internal-ios-frameworks-192aa472f64b ) (I'm probably not writing the podfile as correctly or efficiently as I could, but this seems to fix my issue)

My podfile is therefore as follows:

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