Overview
Swift Package Manger (SPM) is awesome and I love it. It's simple, yet powerful. More importantly it's built into Xcode and allows us to drop 3rd party dependencies.
That said, we wouldn't be where we are today without CococaPods. The team that built CocoaPods did (and still do) an amazing job.
I spend a lot of time in the terminal and managing the devops aspect of iOS development. Over the years, I've refined a thing here and a thing there to avoid issues and optimize flexibility and stability.
This is my personal guide to installing CocoaPods.
sudo or not?
Ruby comes preinstall on macOS. Although handy to have around, it's a system dependency and requires you to use sudo
when installing gems or other system-mutating commands. I really like to keep my system as clean as possible (we don't always have time to reinstall macOS periodically, after all).
For that reason, I avoid using the system Ruby as much as I can. I use virtual environments.
Installing asdf
You can use rbenv, rvm, pyenv, nodeenv, and more. However, I use asdf to install and manage all the versions of different runtimes. One tool to rule them all. 💍
- It gives me the flexibility of using multiple versions of Ruby, Python, Node, Go, Java, etc...
- It makes it easy to nuke and reinstall a version should something go awry
- It doesn't require the use of
sudo
when using the runtime - Most importantly, it leaves the system version of Ruby untouched
Assuming you already have homebrew installed, just run these commands to install asdf
:
Once asdf
is installed, make sure to add the following to your .zshrc
file:
⚠️ I am using an M1 MacBook and my path to homebrew
might be different than yours if you're using an Intel Mac. If you're interested to dig deeper into M1 vs Intel, I suggest watching Josh Holtz's excellent YouTube video on the subject.
Installing Ruby
Before continuing, take note of the current version of Ruby being used:
Remember this version for comparison later.
Once asdf
is installed, you can use the ruby
plugin to install the version of Ruby that you need. You can view the list of available versions by running this:
You'll see a lot of versions available. I typically install the latest stable version supported by the continuous integration (CI) service I use:
This might take a while to install, be patient. 🕦
Once this is done, you want to set the version of Ruby you have just installed as the default version globally on your Mac:
This creates a file in your home directory named .tool-versions
which contains the versions of runtimes to be used in your terminal.
Now is a good time to restart your terminal, ensuring all the previous steps have taken effect properly.
Now check the version of Ruby again:
You should seee that this verions is the new one you installed and not the preinstalled system version. 🎉
Installing CocoaPods
Now that you've done all the work, it's time for the easy part:
The installation might take a while, but that's really all you have to do. Once the installation completes, try it out:
Congratulations!
You have successfully installed CocoaPods without using sudo
. 👏👏👏
Using a Gemfile (optional)
You may have been asking yourself why I'm not installing CocoaPods through homebrew... because I want to pick and lock which version of CocoaPods I am using for a given project.
Homebrew is a great tool; but it doesn't always have the version of a tool you need, especially if you require an old version. Additionally, when you're working on a team and your teammates have installed CocoaPods at a different time than you did, it's possible that some are using a different version than others. This doesn't seem like that big of a deal, until CI starts failing, or some teammates are getting errors when installing dependencies, etc...
It's a good practice to keep everyone on the same version of the tooling.
In order to lock in which version of CocoaPods everyone is using, you can use a Gemfile
.
Installing Bundler
Really?! Another tool? 😡
Yes, I know. It's a lot of tools, but I promise that the advantages outweight the setup cost.
Bundler is to Ruby what CocoaPods is to iOS development: it manages (and locks!) dependencies. In fact, the way CocoaPods works, using a Podfile
and a Podfile.lock
, is entirely based on how bundler
works with a Gemfile
and a Gemfile.lock
.
Start by creating a new file, named Gemfile
, at the root of your project:
Install the Ruby dependencies by running this:
This might have taken a while. It will install cocoapods, all of its dependencies, and most importantly, it will create a Gemfile.lock
file which includes all of the versions of the gems you have just installed.
💚 Add these 2 files to your source control.
The next time someone in your team will install the Ruby dependencies, it will install the versions dictated by the Gemfile.lock
file. This means everyone in your team, as well as all your CI runners, will be using the same version of CocoaPods.
If you want or need to upgrade the Ruby dependencies, simply run:
This will install all the latest version of the dependencies and update the Gemfile.lock
file. 💚 Commit those changes.
Using bundler
The caveat of using bundler, is that you need to run commands in the context of the bundle.
When running pod
commands, you must prefix your commands with bundle exec
. This tells bundler to run the command following the exec
keyword using the versions of the dependencies defined in the Gemfile.lock
.
This is particularly useful when you have have many projects, using different versions of CocoaPods.
If you're using ohmyzsh, you can enable the bundler
plugin to shorten bundle exec
to be
. Or you can add one yourself, add this to your .zshrc
file:
Now you can run pod commands like this:
Conclusion
CocoaPods is a fantastic tool. Have you tried converting a CocoaPods project to an SPM project? 😃
Don't hesitate to reach out, tweet, or slack me.
❄️☃️ This winter is cold. Tell someone you love them.