How to add dependency in Podfile

With the advent of Swift 3.0, Apple has released an official package manager called Swift Package Manager (AKA SPM or SwiftPM), that helps us manage dependencies.

But there are two other package managers out there: CocoaPods and Carthage.

In this tutorial, you will learn about the pros and cons of each package manager, and how to use them to integrate frameworks into your codebase.

You will be using a simple to-do app called

# 1
source 'https://github.com/CocoaPods/Specs.git'
# 2
platform :ios, '9.0'
# 3
use_frameworks!

# 4
target 'EasyToDo' do
  # 5
  pod 'Alamofire'
end
3, to learn about each integration. This app has a backend that allows users to synchronize all their to-do lists.

You’ll use Xcode 10 and Swift 4.2 in this tutorial, but CocoaPods and Carthage also support Objective-C.

Why should I use it?

You might be asking yourself, “Can’t I just copy the source code inside my app project and use that?” Yes, you can, but what will you do if a critical update comes up? You will need to manually follow the repository release updates and keep checking for new versions. That doesn’t sound like fun, does it? Well, you’re in luck! By using a package manager, you can easily make sure that your code is always up to date.

What is a package manager?

Great question! A package manager is a tool that automates the process of installing, upgrading, configuring, and removing a software, or in this case, inside our app.

But what does that really mean? Let's suppose you need to handle network requests inside your app, but you don't want to reinvent the wheel. You just want to use a robust, reliable, well crafted, and well-tested framework.

With a package manager, you can easily manage dependencies inside your software, like Alamofire to help you better handle the network requests inside your to do app.

CocoaPods

CocoaPods is a centralized dependency manager for Swift and Objective-C Cocoa projects. It is open-source and was built with Ruby by many volunteers and the open-source community.

What does centralized mean? Well, CocoaPods is based on a main repository called Specs that hosts all the framework specifications. In order to make it available to others, package developers have to push new versions to this repository by using the

# 1
source 'https://github.com/CocoaPods/Specs.git'
# 2
platform :ios, '9.0'
# 3
use_frameworks!

# 4
target 'EasyToDo' do
  # 5
  pod 'Alamofire'
end
4 command line.

CocoaPods has a wonderful public search feature available on its official website so you don't have to scan the web to find the right dependencies.


Search feature on CocoaPods website

Supported Platforms

All Apple platforms, iOS, tvOS, watchOS, and macOS. CocoaPods command line tool only works on a Mac.

How To Use It

First, you need to install it on your Mac, open Terminal and type

sudo gem install cocoapods

Then, to integrate a dependency using CocoaPods, you have to create a

# 1
source 'https://github.com/CocoaPods/Specs.git'
# 2
platform :ios, '9.0'
# 3
use_frameworks!

# 4
target 'EasyToDo' do
  # 5
  pod 'Alamofire'
end
5 in your project root folder, like the following one:

# 1
source 'https://github.com/CocoaPods/Specs.git'
# 2
platform :ios, '9.0'
# 3
use_frameworks!

# 4
target 'EasyToDo' do
  # 5
  pod 'Alamofire'
end

Now open the Terminal App on your Mac and type

pod install

You have successfully integrated your dependency!

How to add dependency in Podfile

Let's see what you’ve done:

  1. You specified the specs source repository. This allows you to add an external repository, like a private one.
  2. You specified that your app is an iOS app that works on iOS 9 or later. You can set whatever version you want.
  3. You told CocoaPods to integrate your dependencies as Dynamic Frameworks instead of Static Libraries. From Xcode 9, Swift 4, and CocoaPods 1.5.0, you can use Static Libraries for Swift as well. We’ll use Dynamic Frameworks in this tutorial.
  4. You added your app’s name as the target. You can specify different dependencies for every target in your project, for example, a macOS app.
  5. And finally, this is your dependency. In this case, you’re just adding Alamofire. On this line, you can also specify what version of pod you’d like to use. For example, major, minor or patch version.

After you run

# 1
source 'https://github.com/CocoaPods/Specs.git'
# 2
platform :ios, '9.0'
# 3
use_frameworks!

# 4
target 'EasyToDo' do
  # 5
  pod 'Alamofire'
end
6 on the Terminal, a
# 1
source 'https://github.com/CocoaPods/Specs.git'
# 2
platform :ios, '9.0'
# 3
use_frameworks!

# 4
target 'EasyToDo' do
  # 5
  pod 'Alamofire'
end
7 file will be created to let other developers, or even you, add the same version of the same dependencies to your app. If your project is under version control, usually this file is pushed to the repository.

A folder called

# 1
source 'https://github.com/CocoaPods/Specs.git'
# 2
platform :ios, '9.0'
# 3
use_frameworks!

# 4
target 'EasyToDo' do
  # 5
  pod 'Alamofire'
end
8 was also created. Inside this folder, you will find everything is related to the CocoaPods integration. If your project is under version control, this file is usually pushed to the repository too, but this is optional.
From now on, you must use the
# 1
source 'https://github.com/CocoaPods/Specs.git'
# 2
platform :ios, '9.0'
# 3
use_frameworks!

# 4
target 'EasyToDo' do
  # 5
  pod 'Alamofire'
end
9 file, instead of the
pod install
0 file to open your app's source code. This is needed in order to integrate your original app project and the CocoaPods project inside a single workspace.

Go to your Swift file and type

import Alamofire

You can now use Alamofire inside your file!

Advantages

  1. You can search for a dependency on the official CocoaPods website.
  2. Supports both Dynamic Frameworks and Static Libraries (since version 1.5.0).
  3. Automatically manage a dependency’s dependencies. If a dependency relies on another dependency, CocoaPods will handle it for you.
  4. Anyone can easily tell what dependencies your app is using.
  5. It's easy to check if a new version of a dependency is available by using the command
    pod install
    
    1.
  6. If the dependency supports it, you can try the dependency before integrating it into your project by using the command
    pod install
    
    2.
  7. Has an official Mac app to easily manage app dependencies.
  8. Almost every framework supports CocoaPods.

Disadvantages

  1. You will have to wait a long time the first time you install your dependencies, even if it’s just one, as CocoaPods will have to download the main Specs repository on your Mac. This will also happen on every
    pod install
    
    3 command when you want to update your dependencies.
  2. Your main project will be modified to be able to use all of your dependencies. It's also true that you can remove the CocoaPods integration by using the command
    pod install
    
    4.
  3. Every time you build your project, all your dependencies will also be built, which leads to slower build times.

List Of Useful Commands

  • pod install
    
    5 - Create the initial Podfile file for you.
  • # 1
    source 'https://github.com/CocoaPods/Specs.git'
    # 2
    platform :ios, '9.0'
    # 3
    use_frameworks!
    
    # 4
    target 'EasyToDo' do
      # 5
      pod 'Alamofire'
    end
    
    6 - Install the dependencies based on Podfile.lock file.
  • pod install
    
    3 - Update the dependencies based on Podfile file.
  • pod install
    
    8 - Update a dependency based on Podfile file.
  • pod install
    
    9 - Update the local Specs repository, that is no more update on
    # 1
    source 'https://github.com/CocoaPods/Specs.git'
    # 2
    platform :ios, '9.0'
    # 3
    use_frameworks!
    
    # 4
    target 'EasyToDo' do
      # 5
      pod 'Alamofire'
    end
    
    6, but only on
    pod install
    
    3.
  • pod install
    
    1 - Show the outdated dependencies.
  • import Alamofire
    
    3 - Lets you try a dependency.
  • pod install
    
    4 - Removes all the CocoaPods integration in the project.

Carthage

Carthage is a decentralized dependency manager for Swift and Objective-C Cocoa projects. It is open-source and built with Swift by the open-source community.

What does decentralized mean? Unlike CocoaPods, you don't have a main Specs repository. This reduces maintenance work and avoids any central points of failure, but project discovery is more difficult. For example, this means that checking for outdated dependencies means checking every dependency repository instead of a single centralized one.

Supported Platforms

All Apple platforms, iOS, tvOS, watchOS, and macOS. Carthage command line tool works only on a Mac.

How To Use It

First, you need to install it on your Mac. There are two ways to do it:

  1. Download the installer package here.
  2. Open Terminal and type
    import Alamofire
    
    5. You can find out how to install it here.

Then, to integrate a dependency using Carthage, you have to create a

import Alamofire
6 in your project root folder, like the following one:

github "Alamofire/Alamofire"

Now open the Terminal App on your Mac and type

carthage update

You have successfully integrated your dependency!

How to add dependency in Podfile

Let's see what you have done:

  1. You have specified that your dependency is on GitHub and is on the
    import Alamofire
    
    7 repository.

That’s all! But a lot of things happened under the hood.

Carthage created a

import Alamofire
8 file to let other developers, or you, add the same version of the same dependencies to your app. If your project is under version control, you would normally push this file to the repository.

It created a

import Alamofire
9 folder in your project root folder. Inside this folder, it checked out every dependency declared in your
import Alamofire
6. If your project is under version control, you would normally push this file to the repository as well.

It also created a

github "Alamofire/Alamofire"
1 folder inside it, where you will find a folder for every platform that your dependencies support. For example, for Alamofire, a framework that supports all Apple platforms, you will find iOS, Mac, tvOS, and watchOS folders.

If you want to only build dependencies for a specified platform, use

github "Alamofire/Alamofire"
2 command.

Inside every platform folder, you will find all the frameworks that support that platform (you will also find other files and a

github "Alamofire/Alamofire"
3 file, which is used for desymbolising crash logs).

There are a few other steps we need to do (from ):

  1. Drag the built
    github "Alamofire/Alamofire"
    
    4 binaries from
    github "Alamofire/Alamofire"
    
    5 into your application’s Xcode project.
  2. On your application targets’ Build Phases settings tab, click the + icon and choose New Run Script Phase. Create a Run Script in which you specify your shell (ex: /bin/sh), add the following contents to the script area below the shell:
/usr/local/bin/carthage copy-frameworks
  1. Add the paths to the frameworks you want to use under “Input Files":
$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework
  1. Add the paths to the copied frameworks to the “Output Files”:
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Alamofire.framework

Go to your Swift file and type

import Alamofire

You can now use Alamofire inside your file!

Advantages

  1. Supports both Dynamic Frameworks and Static Libraries (since version 0.30.0).
  2. Automatically manage a dependency’s dependencies. If a dependency relies on another dependency, Carthage will handle it for you.
  3. Anyone inside the project will easily know what dependencies your app is using.
  4. It's easy to check if a new version of a dependency is available by using the
    github "Alamofire/Alamofire"
    
    6 command.
  5. Your project builds faster in comparison to CocoaPods as Carthage only builds the frameworks once (when you call the
    github "Alamofire/Alamofire"
    
    7 or
    github "Alamofire/Alamofire"
    
    8 command).
  6. Your project remains untouched since you will only add frameworks and a new build phase.

Disadvantages

  1. (Too) many steps, which make it easy to miss adding a new dependency to the Carthage build phase.
  2. Not every framework supports Carthage.

List Of Useful Commands

  • github "Alamofire/Alamofire"
    
    8 - Fetch and build all the dependencies based on Cartfile.resolved file.
  • carthage update
    
    0 - Fetch and build all the dependencies for specific platforms based on Cartfile.resolved.
  • github "Alamofire/Alamofire"
    
    7 - Fetch and build all the dependencies based on Cartfile file.
  • carthage update
    
    2 - Fetch and build all the dependencies for specific platforms based on Cartfile file.
  • carthage update
    
    3 - Build all the dependencies without fetching them.
  • carthage update
    
    4 - Show the outdated dependencies.

Swift Package Manager

Also known as SwiftPM or SPM, it's been included in Swift since version 3.0. From the official repository:

The Swift Package Manager is a tool for managing distribution of source code, aimed at making it easy to share your code and reuse others’ code.

Swift Package Manager is also used to create backend apps by using frameworks like Vapor, Kitura or Perfect.

Your app can only use corelibs or other dependencies based on top of them. Currently, there are:

  • Foundation - Core utils, it contains String, Array and all the others
  • Dispatch - Concurrency helper also known as Grand Central Dispatch or GCD
  • XCTest - Unit Tests support

Thanks to that, we will create a backend App instead of an iOS App.

Supported Platforms

Currently supports only macOS and Linux 14.04, 16.04, and 18.04.

How To Use It

  • For macOS, you just need Xcode 10;
  • For Linux, you have to install it or use swiftenv, which will even help you manage multiple Swift versions.

To be able to build, test, and use your project, you have to use a specific folder structure, like

carthage update
5 for the source files and
carthage update
6 for tests files. Inside the
carthage update
5 folder, you have to create a
carthage update
8 file. This will be the main App source code.

Now let's create our app package description. Create a

carthage update
9 file inside your project root folder.
Inside it, we have to define all the characteristics of our app:

# 1
source 'https://github.com/CocoaPods/Specs.git'
# 2
platform :ios, '9.0'
# 3
use_frameworks!

# 4
target 'EasyToDo' do
  # 5
  pod 'Alamofire'
end
0

Now open Terminal and type

# 1
source 'https://github.com/CocoaPods/Specs.git'
# 2
platform :ios, '9.0'
# 3
use_frameworks!

# 4
target 'EasyToDo' do
  # 5
  pod 'Alamofire'
end
1

If everything went ok, you have successfully created your App!

How to add dependency in Podfile

See what you have done:

  1. Since this a normal Swift source file, we had to import a module.
  2. You created a
    /usr/local/bin/carthage copy-frameworks
    
    0, this is where you defined all your App characteristics.
  3. Here, you defined your app name.
  4. This is the dependencies array where you defined all the app dependencies.
  5. You declared
    /usr/local/bin/carthage copy-frameworks
    
    1 as a dependency because Alamofire doesn't support Linux. This can even be a local repository.
  6. This is the targets array, you can define more than one target and divide your app in multiple targets, but for now, we only declared one.
  7. This is the real app target.

After running

/usr/local/bin/carthage copy-frameworks
2 on the Terminal, a
/usr/local/bin/carthage copy-frameworks
3 file will be created to let other developers, or even you, add the same version of the same dependencies to your app. If your project is under version control, you would usually push this file to the repository.

A

/usr/local/bin/carthage copy-frameworks
4 folder will be created for you, where you will find everything related to Swift Package Manager. You will find all the dependency repositories and your executable app.

To execute your app, you can type

/usr/local/bin/carthage copy-frameworks
5.

If you are on a Mac, you can even automatically generate the Xcode project with

/usr/local/bin/carthage copy-frameworks
6. From now on, you can use Xcode to build and maintain your app.

Now we can use our dependency inside our app. Open

carthage update
8 source file and type

# 1
source 'https://github.com/CocoaPods/Specs.git'
# 2
platform :ios, '9.0'
# 3
use_frameworks!

# 4
target 'EasyToDo' do
  # 5
  pod 'Alamofire'
end
2

You can now use SwiftNIO inside your file!

Advantages

  1. It’s the new standard build by Apple to create Swift apps.
  2. Automatically manage a dependency’s dependencies. If a dependency relies on another dependency, Swift Package Manager will handle it for you.
  3. Anyone inside the project will easily know what dependencies your app is using.
  4. Works on Linux.

Disadvantages

  1. Currently doesn't support all the platforms like iOS, watchOS, or tvOS.
  2. You have to follow a specific folder structure.
  3. Some features on the Foundation corelib are unimplemented. You can find the current status here.
  4. Creating Unit Tests on Linux is not easy as on macOS. You also have to do additional turnaround.

List Of Useful Commands

  • /usr/local/bin/carthage copy-frameworks
    
    8 - Initialize and create a new package.
  • /usr/local/bin/carthage copy-frameworks
    
    9 - Resolve all the dependencies based on Package.resolved file.
  • $(SRCROOT)/Carthage/Build/iOS/Alamofire.framework
    
    0 - Update all the dependencies based on Package.swift file.
  • /usr/local/bin/carthage copy-frameworks
    
    2 - Build all the source files.
  • /usr/local/bin/carthage copy-frameworks
    
    6 - Generate a xcodeproj file so you can use Xcode to develop.
  • $(SRCROOT)/Carthage/Build/iOS/Alamofire.framework
    
    3 - Generate a xcodeproj file so you can use Xcode to develop and watch for source file folders changes.
  • $(SRCROOT)/Carthage/Build/iOS/Alamofire.framework
    
    4 - Delete all the build artifacts.

What Package Manager Should I Use?

The below flowchart has only some simple questions to help you choose the best package manager that better fits your needs.

Summary

We learned how the package managers available for Apple platforms (even Linux!) differ, how they work, and how to use them. Now it’s up to you to choose the best package manager for your project.

As a next step, why don't you try to create your own framework that supports all the package managers?

How do I add a dependency to pod?

From the CocoaPods repository Specify the name of a Pod library in the pod() function. In the configuration block, you can specify the version of the library using the version parameter. To use the latest version of the library, you can just omit this parameter altogether. You can add dependencies on subspecs.

Is it possible to add a local dependency to .podspec file?

It's not possible to set a local pod as a dependency, but it's possible to set a pod's source for a specific Podfile, which will work the same way.

How do I add a Podfile?

Simple steps to install a pod file:.
Open the terminal..
Command on the terminal: sudo gem install cocoapods..
Set your project path in the terminal..
Command: pod init..
Go to the pod file of your project and add the pod which you want to install..
Added in the pod file: pod 'AFNetworking', '~> 3.0..
Command: Pod install..

How install dependencies with CocoaPods?

Open Terminal or iTerm and execute the gem install cocoapods command to install CocoaPods. Depending on the configuration of your machine, you need to prefix this command with the sudo command. I usually advise people to use a version manager for Ruby, such as RVM or rbenv. I have used both and have settled with rbenv.