Cocoapods: How to solve overlapping pods dependencies between app and framework.

Created on 19 Oct 2012  Â·  20Comments  Â·  Source: CocoaPods/CocoaPods

Currently I'm building a app which uses a framework. But the app and the framework has overlapping pods dependencies. So when I link the app against the framework, I get a ton of compiler warnings and unexpected behavior, such as

objc[33543]: Class RKMutableBlockDictionaryBlockValue is implemented in both /Users/Tony/Library/Developer/Xcode/DerivedData/Proj-chuovrchxcwrraffvylnvroalekh/Build/Products/Debug/FileSystem.framework/Versions/A/FileSystem and /Users/Tony/Library/Developer/Xcode/DerivedData/Proj-chuovrchxcwrraffvylnvroalekh/Build/Products/Debug/MyProj.app/Contents/MacOS/MyProj. One of the two will be used. Which one is undefined.
objc[33543]: Class RKMutableBlockDictionary is implemented in both /Users/Tony/Library/Developer/Xcode/DerivedData/Proj-chuovrchxcwrraffvylnvroalekh/Build/Products/Debug/FileSystem.framework/Versions/A/FileSystem and /Users/Tony/Library/Developer/Xcode/DerivedData/Proj-chuovrchxcwrraffvylnvroalekh/Build/Products/Debug/MyProj.app/Contents/MacOS/MyProj. One of the two will be used. Which one is undefined.
objc[33543]: Class RKOrderedDictionary is implemented in both /Users/Tony/Library/Developer/Xcode/DerivedData/Proj-chuovrchxcwrraffvylnvroalekh/Build/Products/Debug/FileSystem.framework/Versions/A/FileSystem and /Users/Tony/Library/Developer/Xcode/DerivedData/Proj-chuovrchxcwrraffvylnvroalekh/Build/Products/Debug/MyProj.app/Contents/MacOS/MyProj. One of the two will be used. Which one is undefined.

What's the correct way to solve this problem?

Most helpful comment

Thanks for the link @orta. Please correct me if I'm wrong but that doesn't seem to provide a suitable solution for the problem here.

This plugin is for CocoaPods developers, who need to distribute their Pods not only via CocoaPods, but also as frameworks or static libraries for people who do not use Pods.

Whereas here we're on the app developer side who's going to include the pods. I believe that this post explains the problem a little better by doing this schema:

CoolPod -> MyFramework \
                        MyApplication
               CoolPod /

All 20 comments

To clarify, say I have two XCodeProjects, one called "App" another called "Proj2". Both App and Proj2 depends on AFNetworking, and Proj2 produces a framework target which is linked to by App. In this scenario tons of warning result as AFNetworking classes are duplicated. What would be a good way to deal with this?

With the current implementation there is no way to inform the installer that a dependency is being satisfied by indirectly by a Pod. As one of the problems that CocoaPods solves over the frameworks workflow is cross-dependency resolution, with what you want to achieve you are kind of "fighting the system".

The only workarounds that I can think of:

  • Create a podspec for the framework and don't link against it directly.
  • Create a fake (empty or only headers) AFNetworking podspec and require it in at the top of your App Podfile.
  • Remove AFNetworking from your App Podfile (this will not work if another Pod depends on AFNetworking).

@tonyxiao Hello,I met the same problem with you. Could you tell me how do you solve?

Hey guys, I'm also encountering the same issue. Is there any solution using the latest version of CocoaPods?

Thanks for the link @orta. Please correct me if I'm wrong but that doesn't seem to provide a suitable solution for the problem here.

This plugin is for CocoaPods developers, who need to distribute their Pods not only via CocoaPods, but also as frameworks or static libraries for people who do not use Pods.

Whereas here we're on the app developer side who's going to include the pods. I believe that this post explains the problem a little better by doing this schema:

CoolPod -> MyFramework \
                        MyApplication
               CoolPod /

I hear that the next 1.1 beta will support linking pods to a framework, so I think this will be possible i the next release, but isn't right now.

@JonathanBouaziz is MyFramework actually your framework? Or is it a library you got from a 3rd party?

  • If it's yours, I recommend adding this target to your Podfile and defining its dependencies there. The next 1.1.0 beta will have improved support for this.
  • If it's not yours, I recommend defining a podspec for it that defines its dependencies. Better yet, go back to the vendor and ask them to define one :)

@benasher44 it is my framework, the workspace is as followed:

- Workspace
-- Project#1: Main
--- Reference to MyFramework (for target dependencies)
-- Project#2: MyFramework
-- Project#3: Pods

And in the Podfile, each target of each project is being assigned its respective required pods. Does that make sense?

@JonathanBouaziz great! Then adding a target for MyFramework to your Podfile like so should work fine in 1.1.0:

target 'MyFramework' do
  project 'Project2'
  // pod deps go here
end

I encourage you to try this using CocoaPods master, and let us know how it goes!

@benasher44 that's already what's happening:

inhibit_all_warnings!
use_frameworks!
workspace 'Some.xcworkspace'

# ========================
# Pods
#
def basic_pods

    pod 'AFNetworking'
    pod 'JSONModel'
    pod 'CocoaLumberjack'
end

[...]

# ========================
# Frameworks
#
def shared_ios_pods
    platform :ios, '8.0'

    pod 'SDWebImage/WebP'
    pod 'GoogleAnalytics'
end
def shared_tvos_pods
    platform :tvos, '9.0'

    pod 'SDWebImage/WebP'
end
targets = [ 'MyFramework_iOS', 'MyFramework_tvOS']
targets.each do |target_name|
    target target_name do
        project 'MyFramework/MyFramework.xcodeproj'

        if target_name.end_with? "iOS"
            shared_ios_pods

        elsif target_name.end_with? "tvOS"
            shared_tvos_pods
        end


        basic_pods
    end
end

What else is there to do?

That aside, will it be / is it possible to access the MyFramework pods in the Main project? Like embedding AFNetworking into the framework and accessing it from any target that's embedding it.

Yep! In 1.1.0, it recognizes that frameworks are embedded somewhere, and it copies the pods to the places where the framework is embedded, so then you shouldn't have duplicate symbol issues.

On a side note, I recommend reformatting your Podfile for CocoaPods 1.0 target inheritance like this:

inhibit_all_warnings!
use_frameworks!
workspace 'Some.xcworkspace'

pod 'AFNetworking'
pod 'JSONModel'
pod 'CocoaLumberjack'

abstract_target 'MyFrameworks' do
  project 'MyFramework/MyFramework.xcodeproj'
  pod 'SDWebImage/WebP'
  target 'MyFramework_iOS' do
    platform :ios, '8.0'

    pod 'GoogleAnalytics'
  end

  target 'MyFramework_tvOS'  do
    platform :tvos, '9.0'
  end
end

This will make your frameworks properly inherit all of the top level pods, both frameworks will get SDWebImage/WebP, and each framework will have its own platform declared and can declare specific pods that only each framework itself needs.

Great news then!💃 Does the current beta does the job too?

Thanks for the tip!

It does, but it has a bug related to framework targets being in sub-projects, which your project would likely reproduce. This is fixed on master, and the fix will be in an upcoming beta. You can try using CocoaPods master, if you want to try it out before the next beta comes out.

Got it! Will do then, thanks a bunch.

@JonathanBouaziz 1.1.0.beta.2 is out! Please give it a try and let us know how it goes!

Hi, I've the same issue with cocoa pod 1.3.1 and Xcode 9.0.

I use a single Xcode project with one app target and another target for my own framework.
But I have a tons of these errors, and the app crash at launching:

Class AKFCodeVerifyingViewController is implemented in both /Users/loryhuz/Library/Developer/Xcode/DerivedData/BabySittor-ctukdmnmprqalsfilltzzuxoahgb/Build/Products/Debug-iphonesimulator/BabysittorKit.framework/BabysittorKit (0x112312db0) and /Users/loryhuz/Library/Developer/CoreSimulator/Devices/F0DA8FC5-8D1C-4E46-B6C6-2622261971DC/data/Containers/Bundle/Application/46924134-0A79-4FA0-8BFD-D5D4B19DCECE/BabySittor.app/BabySittor (0x10a934838). One of the two will be used. Which one is undefined.

I tried the config @benasher44 mentionned:

platform :ios, '9.0'
use_frameworks!

workspace 'BabySittor.xcworkspace'

def testing_pods
    pod 'Quick'
    pod 'Nimble'
end

def app_pods
    pod 'PhoneNumberKit', '~> 2.0'
end

def main_pods
    pod 'ObjectMapper', '~> 3.0'
    pod 'Moya'
    pod "PromiseKit", "~> 4.0"
    pod 'Bolts'
    pod 'FBSDKCoreKit' 
    pod 'FBSDKLoginKit'
    pod 'FBSDKShareKit'
    pod 'RealmSwift'
    pod 'AWSS3'
    pod 'AccountKit'
    pod 'Firebase/Core'
    pod 'Firebase/Messaging'
    pod 'Firebase/RemoteConfig'
    pod 'Fabric'
    pod 'Crashlytics'
end


abstract_target 'BabysittorProjects' do
    project '../BabySittor/BabySittor.xcodeproj'
    main_pods

    target 'BabySittor' do
        app_pods
    end

    target 'BabysittorKit' do
        target 'BabysittorKitTests' do
            inherit! :search_paths
            testing_pods
        end
    end
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '4.0'
      config.build_settings['MACOSX_DEPLOYMENT_TARGET'] = '10.10'
    end
  end
end

Did you manage to solve this?

@anieduard yes, see this thread https://github.com/CocoaPods/CocoaPods/issues/7126, there is a workaround

Thanks a lot!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sonu5 picture sonu5  Â·  3Comments

steffendsommer picture steffendsommer  Â·  3Comments

Mingmingmew picture Mingmingmew  Â·  3Comments

marzapower picture marzapower  Â·  3Comments

tlandsmancars picture tlandsmancars  Â·  3Comments