CocoaPods vs Carthage vs SPM (Dependency manager in Swift)

Manasa M P
10 min readDec 7, 2020

You can install and manage third party libraries in swift using one of the way mentioned in below.

  • Drag and Drop: Download the 3rd party libraries from version control repository i.e git/github and install those into our project by drag and drop method
  • Using Carthage
  • Using CocoaPods
  • Using swift package manager(SPM)

Most of the app uses Carthage or CocoaPods as a dependency manager. your initial project look like this before adding any dependency manager.

CocoaPods

CocoaPods works well with objective c and swift. This is mostly used swift package manger. CocoaPods comes as a Ruby library and needs to be installed using RubyGem.

How to install CocoaPods?

  1. Open terminal and install sudo gem usin $ sudo gem install cocoapods command and enter password.

2. run pod init . After pod init project look as follow

It creates a single text file called Podfile. To integrate required library into your Xcode project using CocoaPods, you can specify it in your Podfile

3. To open Podfile run open -a Xcode Podfile : The default pod file look like this

4. Add your dependency using CocoaPods in pod file and save

e.g: I’ve taken example of integrating Alamofire library to project, which is commonly used for network call.

Simple Podfile look like this after deleting comment i.e line starts with# and adding almofire library to Podfile. This tells CocoaPods that you need almofire in your project.

5. run pod install . After successful installation of libraries, project looks like this

How to integrate framework into project?

CocoaPods automate the entire process of building, linking the dependency to targets.

How to update dependency version?

  • Change the dependency version in Podfile and save
  • run pod install

What are the changes made by CocoaPods?

You might have noticed that after pod install, CocoaPods has done a lot of changes to your Xcode project. Now it’s time to use Xcode Workspace instead of using xcodeproj to build your app successfully. Xcode workspace contains all dependency.

  • It creates xcode workspace, Podfile, Podfile.lock, Pods directory containing source code of the Pod dependencies and supporting files.
  • Adds some of scripts in build phase and adds library into link binary with libraries.

Which files need to be committed into version control repository?

  • Podfile and Podfile.lock need to be committed into your version control repository. Other developer uses the same version of dependencies using these files.
  • Committing of Pods directory is not required.

How other developers gets notified when you change version of dependencies?

  • Other developer take the pull and run pod install to get latest version of dependencies.
  • If Podfile.lock and Manifest.lock is not in sync, it will throw an error.
  • Manifest.lock have local details about dependencies version used in project and Podfile.lock have details of latest dependencies version used and committed in version control repository

How to remove CocoaPods from project?

CocoaPods integration into your project is easy but de-integrating takes more time. It needs lot of manual work to de-integrate the CocoaPods from your project

  • run pod deintegrate command.
  • Make sure your Pods directory, Podfile.lock, Podfile and test.xcworkspace is removed. If it is not removed then manually delete these files.
  • delete script added by CocoaPods in build phase i.e Check mainfest.lock, Embeded pods framework, remove pod from link binary with libraries and in general tab remove pod from framewroks,libraries and embeded content
  • Finally remove the code snippets which are written using frameworks.

How Xcode build frameworks?

  • CocoaPods build and compile the framework when you’re doing the clean build or pod install or pod update or if pod.lock file is changed.
  • Xcode checks the pod.lock file. If pod.lock file is changed then dependency will be build again by Xcode otherwise it will use the pre-built frameworks.
  • You’re project takes longer time when you do clean build or delete derived data or when pod.lock file is changed.
  • CocoaPods will build all the libraries mentioned in the Podfile for that target
  • CocoaPods depends on pod spec which includes metadata about the project and specifies how it should be built.

How CocoaPods works with static library and dynamic frameworks?

CocoaPods works with both dynamic frameworks and static libraries. CocoaPods 1.5.0 comes with native support for building Swift pods as static libraries. Before CocoaPods 1.5.0, it supports only dynamic frameworks.

  • if you mention use_frameworks! in Podfile, CocoaPods creates dynamic frameworks. otherwise it will creates static libraries.
  • There is no longer restricted into specifying use_frameworks! in their Podfile in order to install pods that use Swift. if your Swift pod depends on an Objective-C pod you will need to enable modular headers.
  • In your Podfile you can add use_modular_headers! to enable the stricter search paths and module map generation for all of your pods, or you can add :modular_headers => true to a single pod declaration to enable for only that pod.
Static libraries with CocoaPods
Dynamic frameworks with CocoaPods

What are the advantages of CocoaPods?

  • It’s easy to add/remove any external framework using CocoaPods
  • CocoaPods automate the entire process of building, linking the dependency to targets

What are the disadvantages of CocoaPods?

  • Hard to integrate with existing Xcode workspace.
  • Hard to remove once it’s integrated
  • CocoaPods takes control of entire project. If something fails, it stops app building. Needs effort on understanding of error.
  • CocoaPods changes the project structure. Takes time to understand the structure
  • Slow down the app build process and It is centralised.
  • Difficult to integrated with Continuous Integration server

Carthage

It is the another dependency manager. Carthage has been written in swift language. It will not change anything in Xcode project. It builds framework binaries using xcodebuild but user needs to integrate those libraries into project. To know more about Carthage click here

How to install Carthage?

There are two ways to install this tool:

  1. Download and run a .pkg installer for the latest release. Download the latest carthage package from git and install it.

2. Using Homebrew package manager.

  • open Cartfile using open -a Xcode Cartfile
  • Add your dependency framework details in Cartfiles and save the Cartfile.

e.g: I’ve taken the example of almofire framework. Cartfile look like this, after adding almofire into Cartfile.

  • run carthage update --platform iOS in terminal. Now your project look like this.

How to integrate framework into project?

  • open Xcode, drag and drop .framework extension directory of dependencies from build directory into Frameworks, Libraries, and Embedded Content section under general tab. e.g: drag and drop Alamofire.framework
  • Select build phase tab. Click on + icon on right side. Select New Run Script Phase .
  • Under run script add /usr/local/bin/carthage copy-frameworks
  • Click the + icon under Input Files and add an entry for each frameworks using $(SRCROOT)/Carthage/Build/iOS/name.framework e.g: $(SRCROOT)/Carthage/Build/iOS/Alamofire.framework

How to update dependency version?

  • Change the dependency version in Cartfile and save
  • run carthage bootstrap --no-build

What are the changes made by Carthage?

Which creates Cartfile.resolved, Carthage directories which contains two sub directories i.e build and checkout and adds some of scripts in build phase and library into link binary with libraries.

  • Cartfile.resolved: It defines exactly which versions of your dependencies Carthage selected for installation. You write Cartfiles in a subset of OGDL: Ordered Graph Data Language. There are two key information in each line of Cartfile.
  1. Dependency origin: It tells Carthage where to fetch a dependency. e.g: git or github
  2. Dependency version: It tell Carthage which version of a dependency you want to use.
  • Build: This contains the built framework for each dependency. You can integrate these into the project
  • Checkouts: This is where Carthage checks out the source code for each dependency that’s ready to build into frameworks

Which files need to be committed into version control repository?

  • Cartfile and Cartfile.resolved need to be committed into your version control repository.
  • Whether you commit the Build and Checkouts directories is up to you. It’s not required.

How you and other developers will be in sync with same version of dependencies?

  • Other developer uses the same version of dependencies using Cartfile and Cartfile.resolved files.
  • If you commit Build and Checkouts, anybody who clones your repository will have the binaries and source for each dependency available.
  • If your not commit the Build and Checkouts directories then other developer need to run carthage bootstrap --no-build after checking out your project. The bootstrap command downloads and builds the exact versions of your dependencies specified in Cartfile.resolved

How to remove Carthage from project?

It’s very simple to remove Carthage from project. It required following steps.

  1. Remove Cartfile, Cartfile.resolved and Carthage directory

2. Delete frameworks from build directory into Frameworks, Libraries, and Embedded Content section under general tab

3. Remove run scripts and input file for frameworks

4. Finally remove the code snippets which are written using frameworks

How Xcode build frameworks?

  • It retrieves the library and binary only once. frameworks are rebuild only when you get new version of any dependency.
  • Xcode will not rebuild any framework when building the project. This speeds up the build process.

How Carthage works with static library and dynamic frameworks?

Carthage only works with dynamic frameworks. It doesn’t work with static libraries.

What are the advantages of Carthage?

  • App build process is fast and It is decentralised.
  • It is written in swift so understanding is easy.
  • It is easy to integrate to existing Xcode workspace and Xcode project.
  • Easy to remove from project.
  • It will not change any project structure.
  • It can be easily integrated with Continuous Integration server

What are the disadvantages of Carthage?

  • It requires too many manual steps to integrate the framework.
  • Not have many contributor.
  • Carthage only works with dynamic frameworks. It doesn’t work with static libraries.

Swift Package Manager

It is another tool to automate the process of downloading, compiling, and linking dependencies. Packages are simple repositories that contain one or more libraries and executables.

How to install SPM?

due to Xcode 11 and above, apple provides a way to install swift packages directly into your project as follows.

  • Open xcode. Select file Select Swift packages Select Add Package Depenedency
  • New window will open add dependency url click on Next
  • After verifying the url New window will show for adding version/commit id/brach of dependency.
  • Click on Next and finally click on Finish

E.g: After adding dependency your project look like this

How to integrate framework into project?

SPM automate the entire process of building, linking the dependency to targets.

How to update dependency version?

selecting File ▸ Swift Packages ▸ Update to Latest Package Versions

What are changes made by SPM?

  • It adds new tab Swift Packages and adds dependency library into link binary with libraries and swiftpm directory
  • swiftpm contains Package.resolved
  • You can see these files inside your .xcodeproj directory.
    follow these steps to check the files Right click on [appName].xcodeproj Show Package Contents project.workspace xcshareddata swiftpm Package.resolved

Which files need to be committed into version control repository?

If you change any dependency version then make sure to commit Package.resolved file. So that everyone is using the same version of a package dependency.

How you and other developers will be in sync with same version of dependencies?

  • When you add a package dependency to a project, Xcode creates the Package.resolved file.
  • It lists the specific Git commits to which each package dependency resolves and the checksums of binary dependencies.

How to remove SPM from project?

It’s very easy to remove the dependency from project.

  • Click on project and then click on Swift Packages tab
  • Click on the dependency which you need to remove and then click - button.
  • Finally remove the code snippets which are written using frameworks

What are the advantages of SPM?

  • It’s build by Apple to create Swift apps.
  • If a dependency relies on another dependency, Swift Package Manager will handle it for you.
  • Initially it supports only for macOS and Linux. Since the release of Swift 5 and Xcode 11, SwiftPM is compatible with the iOS, macOS and tvOS
  • It can be easily integrated with Continuous Integration server

What are the disadvantages of SPM?

  • It is compatible with Swift 5 and Xcode 11
  • Below Xcode 11, SPM is supported only for mac and linux

Conclusion

Every dependency manager has pros and cons. you have to decide which one is good for your project. My personal preference don’t use any dependency manager try to use apple provided default frameworks until it is really needed.

LAST REMARKS

I hope you find this blog helpful. If you enjoyed it, feel free to hit the clap button below 👏 to help others find it! and follow me on Medium. Thanks for reading. ❤❤❤❤

--

--