Cocoapods: Using pods in extensions is broken in 1.2.0 (the "Target has frameworks with conflicting names" bug, again)

Created on 9 Feb 2017  路  9Comments  路  Source: CocoaPods/CocoaPods

Report

What did you do?

(See below)

What did you expect to happen?

Install all pod dependencies correctly, for all targets.

What happened instead?

Getting the Error - [!] The 'Pods-App' target has frameworks with conflicting names: realm, realmswift.

CocoaPods Environment

Stack

   CocoaPods : 1.2.0
        Ruby : ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin16]
    RubyGems : 2.4.8
        Host : Mac OS X 10.12.4 (16E154a)
       Xcode : 8.3 (8W120l)
         Git : git version 2.11.0 (Apple Git-80)
Ruby lib dir : /Users/jonaszaugg/.rvm/rubies/ruby-2.3.0/lib
Repositories : master - https://github.com/CocoaPods/Specs.git @ 860de241644c9ebf2c3402b314f8e1325e6cf61d

Installation Source

Executable Path: /Users/jonaszaugg/.rvm/gems/ruby-2.3.0/bin/pod

Plugins

cocoapods-clean            : 0.0.1
cocoapods-deintegrate      : 1.0.1
cocoapods-docs             : 0.2.0
cocoapods-open             : 0.0.8
cocoapods-plugins          : 1.0.0
cocoapods-search           : 1.0.0
cocoapods-stats            : 1.0.0
cocoapods-superdeintegrate : 0.0.1
cocoapods-trunk            : 1.1.2
cocoapods-try              : 1.1.0

Podfile

(Please see the variations below)

Project that demonstrates the issue

(I'll add one if necessary but I haven't one at hand at the moment)

This was meant as a comment on #6446 but the more I wrote, the further I got from the OP's issue, I think. My issue is very extensively described on StackOverflow but it can be summed up as:

  • Main app with an extension, they share code through a framework of your own (3 targets: App, Extension and Shared)
  • Main app uses some pods for UI, shared framework uses pods for networking, database, etc. and you don't want these to be included in the main app's target (separation of concerns).
  • The extension uses the shared framework but needs one or more of the pods to be linked to compile

This is not the same issue as #5643 because there's no question here of pods with different subspecs. The issue here has been referred to multiple times, often being wrongly assimilated to the aforementioned issue. Specifically:

What changed with 1.2.0? Before, you could easily do the following:
````ruby
use_frameworks!

target 'App' do
# e.g. UI specific pods
pod 'PureLayout'
end

target 'Shared' do # A framework imported in both other targets
pod 'Alamofire'
pod 'RealmSwift'
pod 'KeychainAccess'
end

target 'Extension' do
# We need the explicit duplicate pod for some reason,
# usually because the extension uses some of its getters
# and not only pure "Shared" code
pod 'RealmSwift'
end
````

Now this returns the conflicting names error. The logical workaround would, trying to keep the _exact same_ "access rights":
````ruby
use_frameworks!

target 'App' do
# e.g. UI specific pods
pod 'PureLayout'
end

abstract_target 'Abstract' do
pod 'RealmSwift'

target 'Shared' do
pod 'Alamofire'
pod 'KeychainAccess'
end

target 'Extension' do
# Because we only need Realm in our extension
inherit! :search_paths
end
end
However a "real" target seemingly cannot inherit from an abstract target. This can easily be seen because the Pods-Extension.xcconfig files are completely devoid of references to the pods it should inherit. That's a first bug IMO. Therefore you make a compromise and decide to let the extension have access to all the `Shared` target's pods: ruby
use_frameworks!

target 'App' do
# e.g. UI specific pods
pod 'PureLayout'
end

target 'Shared' do
pod 'Alamofire'
pod 'RealmSwift'
pod 'KeychainAccess'

target 'Extension' do
inherit! :search_paths
end
end
But this does not fully work (and that's the other bug IMO) : `inherit! :search_paths` is great for the search paths but no good for linking the binaries. If we were only using pure Shared.framework code, it would be fine but the reason we had the pod listed both under the `Shared` target and the `Extension` target in the first place is because the extension uses some code directly (e.g. Realm's getters or methods). Compiling yields the following error:
Undefined symbols for architecture x86_64:
"RealmSwift.Results.last.getter : A?", referenced from:
Extension.TodayViewController.widgetPerformUpdate (completionHandler : (__C.NCUpdateResult) -> ()) -> () in TodayViewController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
``` The only way here is manually linking "Realm.framework" inside theExtension`'s Build Phases. This is of course easy to do but you go from an easy Podfile that works "out of the box" to a more convoluted one that needs you to do some work afterwards and doesn't respect your original structure.

To sum up what's buggy:

  • inherit! :search_paths doesn't work for inheritance from an abstract_target
  • inherit! :search_paths isn't sufficient when linking to the libraries is required, and I believe this is _always_ the case if we've already had to add the pods to the Extension target in our original Podfile. Manual linking to the framework is required.

Sorry for the (extremely) long comment but I think this general issue deserves some attention. Thanks for reading and cheers!

awaiting input

Most helpful comment

Ok now I basically hate myself : adding import RealmSwift to the Extension's code fixes (or at least circumvents) the second bug. Why do I need it now explicitly when it worked in previous with only import Shared? I wonder (and maybe it should still be investigated).
The first bug still stands, but is mostly an issue of elegance : having the search paths of only a few and not all frameworks. I've noticed that all pods are "importable" everywhere, regardless of where the pods are defined... I thought it would "limit" the import statements to the target where the pod is defined in the Podfile.

Apparently I'm not alone in the confusion regarding linking, new syntax, etc. : https://github.com/CocoaPods/CocoaPods/issues/5383#issuecomment-220633840.

TL;DR: the real questions are

  • Should the [!] The 'Pods-App' target has frameworks with conflicting names error be limited to having multiple pods with different subspecs, therefore restoring the pre-1.2.0 behaviour?
  • Should inherit! :search_paths also work for abstract targets?
  • Should this common pattern be explained in the Podfile syntax reference, seeing how many times the "Target has frameworks with conflicting names" bug has been mentioned?
  • I guess the deprecated link_with, which was the preferred solution in my case in the previous syntax, did link the frameworks. Should similar behaviour be reintroduced?

All 9 comments

Ok now I basically hate myself : adding import RealmSwift to the Extension's code fixes (or at least circumvents) the second bug. Why do I need it now explicitly when it worked in previous with only import Shared? I wonder (and maybe it should still be investigated).
The first bug still stands, but is mostly an issue of elegance : having the search paths of only a few and not all frameworks. I've noticed that all pods are "importable" everywhere, regardless of where the pods are defined... I thought it would "limit" the import statements to the target where the pod is defined in the Podfile.

Apparently I'm not alone in the confusion regarding linking, new syntax, etc. : https://github.com/CocoaPods/CocoaPods/issues/5383#issuecomment-220633840.

TL;DR: the real questions are

  • Should the [!] The 'Pods-App' target has frameworks with conflicting names error be limited to having multiple pods with different subspecs, therefore restoring the pre-1.2.0 behaviour?
  • Should inherit! :search_paths also work for abstract targets?
  • Should this common pattern be explained in the Podfile syntax reference, seeing how many times the "Target has frameworks with conflicting names" bug has been mentioned?
  • I guess the deprecated link_with, which was the preferred solution in my case in the previous syntax, did link the frameworks. Should similar behaviour be reintroduced?

I'm also experiencing this problem. My solution was to do as you said and use inherit! :search_paths which works only when building to a device. When I try and archive the app it fails "No such module" for every pod I try and use in the extensions

Hi,

Any workaround for that? I'm trying to use same pods in both app and its extension and it does not work.
I asked a question on stakoverflow here.

@ooii : I'll refer you to my question and answer here on Stackoverflow.

I tried you podfile example, without the MyAppKitpart because I don't have it, and it does not work. It exists with Cannot load underlying module for 'FileKit' in the extension part.
Here is the podfile I'm using:

use_frameworks!
target 'myApp' do
            pod 'SVProgressHUD', '~> 2.1.2'
            pod 'Alamofire', '~> 4.0'
            pod 'FileKit', '~> 4.0.1'
target 'myAppExtension' do
        inherit! :search_paths # Because else we get the "conflicting names"
end
end

OK, tried to build one more time and now it works... Thanks.

For me this works:

target 'Poncho' do
  pod 'Mixpanel-swift', '~> 2.0'
end

target 'Extension1' do
  pod 'Mixpanel-swift-appex', '~> 2.0'
end

target 'Extension2' do
end

But this doesn't:

target 'Poncho' do
  pod 'Mixpanel-swift', '~> 2.0'
end

target 'Extension1' do
  pod 'Mixpanel-swift-appex', '~> 2.0'
end

target 'Extension2' do
  pod 'Mixpanel-swift-appex', '~> 2.0'
end

In order to fix it you must add mixpanel-appex to the main target too:

target 'Poncho' do
  pod 'Mixpanel-swift', '~> 2.0'
  pod 'Mixpanel-swift-appex', '~> 2.0'
end

target 'Extension1' do
  pod 'Mixpanel-swift-appex', '~> 2.0'
end

target 'Extension2' do
  pod 'Mixpanel-swift-appex', '~> 2.0'
end

This forces the main target to link to mixpanel-appex also, which is completely unwanted :/

There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates.

Yeah we can close this. For those who'd like to know what I did, I refer you again to Stackoverflow: https://stackoverflow.com/questions/42114122/using-cocoapods-in-an-app-extension-using-a-framework.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

k06a picture k06a  路  3Comments

dawnnnnn picture dawnnnnn  路  3Comments

iosdev-republicofapps picture iosdev-republicofapps  路  3Comments

steffendsommer picture steffendsommer  路  3Comments

luhui picture luhui  路  3Comments