CocoaPods: The Elegant Solution To Installing The Same Pod In Multiple Targets

One of the most exciting things about Xcode 7 is the ability to natively UI Test (thanks Apple!). So of course that was my priority when I started a new Xcode 7 / Swift 2 project. I really enjoy using Quick and Nimble for my unit tests, so I wanted to use these libraries for my UI Testing as well.

Installing Quick and Nimble is easy with CocoaPods. The issue, however, is that you need to install Quick and Nimble only to your test targets.

The Ugly But Works Solution

The initial way to do it is to have Quick and Nimble in two targets in your Podfile:

# Podfile

platform :ios, '9.0'

use_frameworks!

# My other pods

target 'MyTests' do
    pod 'Quick', '0.5.0'
    pod 'Nimble', '2.0.0-rc.1'
end

target 'MyUITests' do
    pod 'Quick', '0.5.0'
    pod 'Nimble', '2.0.0-rc.1'
end

I did not like repeating the Quick and Nimble twice here – every time I need to upgrade the versioning, I’ll need to change it in two places…

The Wrong Solution

So I Googled around, and found that I need to be using link_with. I immediately assumed that everything below link_with only applied to the targets I specified:

# Podfile

platform :ios, '9.0'

use_frameworks!

# My other pods

link_with 'MyTests', 'MyUITests'

pod 'Quick', '0.5.0'
pod 'Nimble', '2.0.0-rc.1'

Turns out, I was completely wrong about what link_with actually does and how it works. It ended up installing Quick and Nimble to my main app target in addition to my testing targets!

The Elegant Solution

So I went to straight to the expert – Core Contributor to CocoaPods @NeoNacho, who pointed me to the following elegant solution:

# Podfile

platform :ios, '9.0'

use_frameworks!

# My other pods

def testing_pods
    pod 'Quick', '0.5.0'
    pod 'Nimble', '2.0.0-rc.1'
end

target 'MyTests' do
    testing_pods
end

target 'MyUITests' do
    testing_pods
end

I keep forgetting that a Podfile is just a ruby file! Thanks @NeoNacho for saving the day!

Enjoy the article? Join over 14,500+ Swift developers and enthusiasts who get my weekly updates.

  • Hi Natasha, I was using “link_with” on my Today Extension Target, but I was getting the error: “dyld: Library not loaded: @rpath/Alamofire.framework/Alamofire”.

    Now I’m trying to use the last solution that you mentioned, but now I’m with other error “ld: framework not found Pods”.

    Do you have any ideia why it happen? I did not find any answer on Stack or Gist.

    Thanks

    • Do you have the latest version of CocoaPods?

      • Hi Natasha, sorry for the delay to reply. Yes, I’m using the last version 0.38.1.

    • From my understanding :exclusive => true means that ONLY the pods in the block will be added to these targets. In my case, I want my other pods (AFNetworking, etc) to also be added to the test targets.

  • warpling

    If I want to use a framework but ONLY in testing. Can I just add it after testing_pods in the MyUITests target? I was trying that but running into linking issues.

    • Yes, that should work. The linking issue is likely due to something else.

      • warpling

        Ended up being a Derived Data issue I think. It’s working now thanks!

  • Cristián Arenas Ulloa

    You can also just not use targets and they’ll be shared, like this:

    # My other pods
    pod ‘Quick’, ‘0.5.0’
    pod ‘Nimble’, ‘2.0.0-rc.1’

  • Orgmir

    Version 1.0 for cocoapods is out! This means that they simplified it and now you have to declare a target. Also you can use abstract_targets to declared shared dependencies.

    abstract_target ‘Tests’ do
    pod ‘Quick’, ‘0.5.0’
    pod ‘Nimble’, ‘2.0.0-rc.1’

    target ‘MyTests’ do
    end

    target ‘MyUITests’ do
    end
    end

    More info in the blog post: http://blog.cocoapods.org/CocoaPods-1.0/

    • Dennis

      All, version 1.0.0 is just a beta, so you can not use it in the production

  • Thank you, Natasha

  • Chanchal Raj

    You know what you have saved my life today, I wish I could give you a party today.. 🙂 Thanks a lot.

  • Fernux

    So, im trying to work on a GBA coding. Can anyone fix this for me?:

    source ‘https://github.com/CocoaPods/Specs.git’

    platform :ios, “7.0”

    inhibit_all_warnings!

    link_with ‘GBA4iOS’, ‘GBA4iOS-Simulator’

    pod ‘RSTWebViewController’, :git => ‘https://github.com/rileytestut/RSTWebViewController-Legacy.git’

    pod “AFNetworking”, “~> 2.4”

    pod “PSPDFTextView”, :git => ‘https://github.com/steipete/PSPDFTextView.git’

    pod “Dropbox-iOS-SDK”, “~> 1.3.0”

    pod “CrashlyticsFramework”, “~> 2.1.0”

    (“Link_with ‘GBA4iOS’, ‘GBA4iOS-Simulator” is the line i need fixed, all other lines work, but i have no clue how to fix this.

  • Oleg

    Love it!

  • Woah thanks for this!

  • ChibiJosh

    Thanks, Natasha! This saved me a lot of complexity in my current project.

  • Ivan Berdnikov

    Thank you!

  • Chris

    This might be the first time I was compelled to comment, but not the first time you’ve offered an elegant solution to an iOS problem I was having. Thanks very much!

  • Abhishek Bedi

    Targets that want to know about the pods for a target but don’t need linking (for example, Test targets) can define that they inherit pods via their search paths (inherit! :search_paths).
    :exclusive => true and link_with have been removed in favour of the above.

    http://blog.cocoapods.org/CocoaPods-1.0-Migration-Guide/