52

I'm creating a new Cocoa Touch Framework (MyFramework.framework), which will have a dependency on Alamofire. This framework will be written in Swift. As a test I started a new Cocoa Touch Framework project:

File > New > Project > Framework & Library > Cocoa Touch Framework

Then, in the terminal I performed:

pod init

under this projects directory. In the newly created Podfile I added the following:

source 'https://github.com/CocoaPods/Specs.git'
# Uncomment this line to define a global platform for your project
platform :ios, '8.0'
# Uncomment this line if you're using Swift
use_frameworks!

pod 'Alamofire', '~> 3.0'

Once again, in the Terminal I performed:

pod install

and started coding away.

Everything seemed well and good till I used the MyFramework.framework Product in a Single View Project. When I attempt to run the project I get the following issue:

dyld: Library not loaded: @rpath/Alamofire.framework/Alamofire
Referenced from: /Users/me/Library/Developer/CoreSimulator/Devices/87DA70B6-49BF-441E-BD81-F4A80B0792CF/data/Containers/Bundle/Application/2E414EA8-7E54-4D71-9295-566D4FAAADE2/test.app/Frameworks/MyFramework.framework/MyFramework
Reason: image not found

I thought that Cocoa Touch Framework projects were inherently Dynamic, and therefore would include all dependencies.

Can anyone tell me why this is happening and how I may be able to fix it? Is this an issue with CocoaPods or am I missing something?

I'm a noob to Stack Overflow so please let me know if you need more information from me.

Thanks!

bneu
  • 573
  • 1
  • 4
  • 10

2 Answers2

32

Unfortunately CocoaPods doesn't support use with Cocoa Touch Framework target. I found a few references to this while digging through their issues on GitHub:

We don't really support integrating Pods into framework targets...
-neonichu on Nov 4, 2015

and

...in order for this to "just work", CP would need to do a recursive analysis of dependencies in your Xcode project and also somehow ensure that you would never use the build product in another context.
-neonichu on Jul 7, 2015


So far I've found two ways to deal with the issue:

The right way is to create a new pod spec for your framework and bring it in to your main project via CocoaPods. This resolves all of the problems CococaPods has with the dependency graph and is the recommended solution from the CocoaPods developers.

The easy way is to include the pods from your framework in your main project. This seems to work, but frankly I don't know why. This is the Podfile from my test project:

platform :ios, '9.0'
use_frameworks!

def myfirstframework_pods
    pod 'Alamofire', '~> 3.0'
end

target 'MyApp' do
    pod 'SwiftKeychainWrapper', '~>1.0'
    myfirstframework_pods
end

target 'MyFirstFramework' do
    myfirstframework_pods
end
Dallas Edwards
  • 552
  • 7
  • 11
  • 2
    The reason why this works is that the framework you are buidling is happy as long is its dependencies are embedded in the app (just link them, and they are embedded by the app). Apple seems to very picky about including frameworks - the only place where they should be added is in the app. This is to avoid many different frameworks adding different versions of frameworks which could cause havoc. I need only mention "java classpath" to give a picture of the other extreme. So yes, using frameworks in frameworks is very difficult, but can be done using so-called umbrella headers. – martin.code Jan 12 '17 at 08:48
  • 1
    The "easy way" will give you an "[!] The 'Pods-MyApp' target has frameworks with conflicting names: googletoolboxformac" for certain libraries, such as Firebase. – José Jul 13 '17 at 11:12
  • 1
    Very helpful post! – VaporwareWolf Jan 02 '18 at 22:44
  • The easy way works! Only took a few hours to figure out the linker error caused by what I assume were leftover link flags in the main projects build settings from previously not having `use_frameworks`. – WCByrne Mar 23 '18 at 08:33
  • 1
    @Dalla Edwards can you describe the right way in detail? – Talib Shabbir Hussain Jul 23 '18 at 13:02
  • For **the right way**, the answer below by _humblePilgrim_ gives a good reference. – inexcii Aug 08 '18 at 10:07
  • The right way -unfortunately- fails when your framework uses static library pods like Firebase ones. You should either go for second way or remove *use_frameworks!* line which makes everything worse. – Arda Oğul Üçpınar Apr 20 '19 at 21:39
  • 1
    So, I am trying to do something similar. Basically I now created an empty **Cocoa Touch Framework** that imports some CocoaPods. This seems to work well. But when I use the framework in a project, I cannot access public functions from CocoaPods that were imported in the framework. Any idea how that could be done? – Jeroen Aug 08 '19 at 06:17
1

Try adding the dependency on Alamofire in the framework's podspec as below

Pod::Spec.new do |s|

# Other setup 

# Dependencies
s.dependency "Alamofire"
# Other dependencies if any
humblePilgrim
  • 1,818
  • 4
  • 25
  • 47