How To: Get Started With CocoaPods
CocoaPods is a package manager for iOS apps. In this tutorial, you’ll learn how to use CocoaPods to integrate third-party libraries into your iOS apps.
Learning how to work with build tools, such as CocoaPods, is a must-have for practical iOS development. CocoaPods makes dealing with dependencies easy, and conveniently helps you to keep your project up-to-date with the latest library versions.
In this tutorial, we’ll get into:
- What CocoaPods is and how it works
- How to install pods into your iOS app project
- How semantic versioning works, and why that’s important
- How to work with the
And a whole lot more! Let’s get to it.
- What’s CocoaPods?
- How To Install CocoaPods
- The Podfile
- Integrating CocoaPods With Xcode
- Further Reading
Imagine you’re working on an iOS app, and you want to use a third-party library in your project. That third-party library – a so-called dependency – includes code that you want to use in your app, such as for HTTP networking, working with databases, or handling JSON. How are you going to “add” that code to your own iOS app project?
A few approaches might work:
- You download the library’s code from GitHub, or from the author’s website, and copy it manually into your Xcode project
- You use a git submodule to add the code to your project, and then sync it via Git
- You use a package manager, such as CocoaPods, Carthage or Swift Package Manager
Of those 3 options, using a package manager makes the most sense. Here’s why:
- A package manager helps you manage libraries your code depends on, so it’s easier to add and remove dependencies, and to see exactly what third-party code your project relies on
- A package manager automatically adds the latest version of a library to your Xcode project, with just a few lines of configuration – it’s super convenient
- A package manager can work with any release version of a library, i.e. you can specify exactly which version of a library you want, which makes keeping your code conflict-free and up-to-date a lot easier
- A package manager typically resolves dependencies between libraries, so you won’t run into conflicts when two libraries both rely on the same sub-library
- A package manager automatically downloads, compiles and links libraries, which speeds up project compile times considerably
In this tutorial, we’ll focus on CocoaPods. It’s the oldest and most mature package manager for iOS (and Mac, tvOS, etc.) and it’s incredibly easy to use.
Here’s how CocoaPods roughly works:
- You configure the libraries you want added to your iOS app projects in a Podfile, which lists “pods” that need to be integrated with your project, including versions you prefer
- With a few commands, CocoaPods downloads these libraries (usually from GitHub) and then adds them to a separate Xcode project
- Both projects are linked together and added to an Xcode workspace, which you’ll use to further develop your iOS project
- When you compile your app, the Pods project is compiled too, and linked with your iOS project, which means that your project can use the code from the libraries at runtime
A pod also uses a special configuration file, called a “Podspec”, which includes information about the third-party library, such as additional dependencies, versions, license information, and so on. Here’s an example podspec, from Alamofire.
CocoaPods maintains a list of all available libraries and Podspecs. This list will get downloaded the first time you use CocoaPods, and may sometimes need to be re-synced and updated. Because of these Podspecs, CocoaPods knows exactly how to add any third-party library to your iOS project. You can find all libraries on cocoapods.org.
The biggest difference between CocoaPods and Carthage, is that CocoaPods changes your Xcode workspace, whereas Carthage merely builds dependencies and lets you add them to your project yourself. Also, Carthage is decentralized, whereas CocoaPods downloads so-called “specs” from a central location.
How To Install CocoaPods
Installing CocoaPods is fairly easy. CocoaPods is built with Ruby, a popular and robust programming language. It’s distributed as a so-called “gem”, which is – how meta! – Ruby’s way of package management. Ruby is installed by default on macOS, so you can use it rightaway.
To install CocoaPods on your Mac, open Terminal and execute the following command:
$ sudo gem install cocoapods
Don’t type the
$ sign. In books, tutorials, courses etc. that sign denotes a command that needs to be executed on the command-line, like Terminal.
CocoaPods will now install system-wide on your Mac. You may need to input your administrator password, because the
gem command temporarily needs administrator access to install CocoaPods for the duration of the installation.
If you need to update CocoaPods to a newer version later on, you can just run
sudo gem install cocoapods again. CocoaPods will tell you when a new version is available, if you run any of its commands. It’s a good idea to keep CocoaPods up-to-date, especially around new Xcode releases.
Now that CocoaPods is installed, let’s move on!
A Podfile is the central configuration file that contains information about what pods you want to use in your iOS app project. It also typically includes some build settings.
Here’s an example Podfile:
source 'https://github.com/CocoaPods/Specs.git' platform :ios, '11.0' target "RecipeApp" do pod 'Firebase', '5.4.0' pod 'FirebaseUI', '5.0.1' pod 'Bugsnag' pod 'MBProgressHUD' end
The Podfile is an actual plain text file that’s added to your project’s root directory, i.e. the same directory that your project’s
.xcproj file is in.
You can create a new file in Xcode by choosing
File -> New -> File..., then choose the Empty template, click Next, and name the file
Podfile, so no extension or anything else. Make sure to save it in the same directory as your Xcode project file.
Always add the Podfile to the same directory your
.xcproj file is in! Otherwise CocoaPods won’t be able to find it.
And here’s what all those lines mean:
sourceparameter points CocoaPods to the Podspecs repository. In the above code, it uses the default, but you can also use CocoaPods to run your own private pod repository, for example for in-house libraries.
platformparameter indicates that this Podfile is to be used on iOS 11. This helps CocoaPods select the appropriate versions, or warn you that a library isn’t available for a particular iOS version. It’s smart to set
platformto the same version as the iOS Deployment Target in Xcode.
targetblock lists the pods you want to use in your project. The target name, i.e.
"RecipeApp"in the above example, needs to match the right target in Project Settings. It’s most likely exactly the same as your project’s name. You can also define additional targets here, for unit testing for example.
pod parameter deserves some more attention, so let’s take a closer look:
pod 'Firebase', '5.4.0'
The syntax is simple: start with
pod, then the pod name, and then a version number. You can find the exact names of pods on cocoapods.org, and most GitHub project pages also tell you what the name of their library is. Don’t forget comma(s)
, and the single quotes
' though – it’s easy to make a typo.
A pod’s version number is important, because you can use some special syntax to fine-tune what library versions you want to work with. Let’s take a look at a few examples.
- No version number, i.e.
pod 'Firebase', indicates that you want to use the latest version of a pod marked for production (i.e., not development versions). It’s smart to use this initially, and throughout the app development process, until you publish or release your app.
- A fixed version number, i.e.
pod 'Firebase', '5.4.0', indicates that you want to use a specific version of a library. It’s smart to pin your project to a specific version after you’ve released the project, and until you actively get to work updating your iOS project.
- Using logical operators such as
<=, you can indicate that you want to use any version higher or lower than a particular version. You probably only need this in specific versions, so it’s smarter to use the next option, optimistic versioning.
- Using the optimistic operator
~>and semantic versioning, i.e.
pod 'Firebase', '~> 5.4', you can indicate that you want to use any version from 5.4 up to 5.5, but not including 5.5. This allows you to automatically upgrade as patches come out, without risking to go into a higher major or minor version.
It’s worth noting here that CocoaPods, and many software packages and apps, use semantic versioning. In short, that means that version numbers follow the
x.y.z format, or better known as
- The first number is the major version, such as Alamofire 4 or Firebase 5. Major versions typically include code-breaking changes, entirely new features, or even entire rebuilds of a library. Upgrading between major versions can be a lot of work.
- The second number is the minor version, such as Firebase 5.4 or Swift 4.2. Minor versions typically include new features that are backwards compatible. So, when a library’s release timeline includes something new that’s added, a version can be bumped from
1.1. It’s smart to be open to these kinds of updates, because they typically make a library better.
- The third number is the patch version, such as Firebase 5.4.1. Patches usually include bug fixes, so it’s often important you stay up-to-date with the most recent patches for a library.
Now you hopefully see that the optimistic operator
~> is quite useful, because it allows you to specify a group of versions you want to stay up-to-date with, while avoiding to “go over” a certain minor or major version.
Alright, now that your Podfile is in place – let’s get to work integrating it with your Xcode project.
It’s good practice to browse to your favorite library on GitHub, and click the Releases button. On that page, you can see the latest releases of the project, including their version numbers and release notes. Can you spot the different major, minor and patch versions? Some libraries even work on multiple major versions at once!
Integrating CocoaPods With Xcode
Now that the Podfile has been set up, CocoaPods can integrate the libraries with your Xcode project.
To do so, open Terminal on your Mac and use
cd to browse to your Xcode project’s directory. Something like this:
$ cd ~/Documents/XcodeProjects/RecipeApp
Then, simply run the following command in Terminal:
$ pod install
CocoaPods will now read your Podfile, download the appropriate versions of pods listed within, and add them to an Xcode workspace.
Quick Note: CocoaPods will download the main Podspec the first time you use
pod install, which is a large file, so it may take a while to download. You may or may not get progress updates, so it may appear as if Terminal is frozen – but it’s not.
It’s important that from this point on, you use the
.xcworkspace file to develop your app project. You can simply double-click on that file to open the workspace. You’ll see two projects inside: your original project, and a Pods project that CocoaPods added.
And that’s all there is to it! You can use the library in your own iOS app project, and conveniently manage your project’s dependencies from now on.
Quick Tip: If your original Xcode project appears “collapsed” when opening the workspace, make sure to first close the original project in Xcode, and then reopen the workspace.
CocoaPods has a few commands that come in handy:
pod install– used initially, and when adding or removing pods
pod outdated– used to list pods that have newer versions available
pod update– used to update pods listed in the Podfile, i.e. find newer versions, and install them if available
A common misconception is using
pod update when you’re only adding or removing pods in the Podfile. The
pod update command is intended to update pods to a newer version, if they’re available. You can also update specific pods with
pod update [podname].
It’s worth noting here that CocoaPods keeps track of which pod versions are installed in your project with a file called
Podfile.lock. It’s a plain text file, saved in your project’s root directory, and – why don’t you have a look at it?
Podfile.lock to compare the currently installed version of a library against a newly available library version, while taking into account the version constraints you set in your Podfile.
Are you using version control in your project, such as Git? Always push and commit the
Podfile.lock, otherwise CocoaPods has no way of knowing which pod versions are integrated with the project.
You may choose to include the
/Pods directory, i.e. the pods themselves, into source control. My personal preference is including them, because it adds some safety and integrity to a project, for example when a library goes AWOL, and because you can build and run the project right after cloning it from the repository.
Working with build tools like CocoaPods, or any other package manager, is one of those skills that every practical iOS developer needs to master. CocoaPods makes dealing with dependencies a whole lot easier, and it helps you avoid conflicts in your iOS projects.
In this tutorial, we’ve looked at:
- What CocoaPods is and how it works
- The importance of the Podfile
- Made a short detour into semantic versioning
- How to install pods into your project
Want to learn more? Check out these resources:
Code Swift right in your browser!
Go to the Swift Sandbox