Carthage Tutorial: Getting Started

In this Carthage tutorial, you’ll learn what Carthage is, how to install it and how to use it to declare, install and integrate your dependencies. By Felipe Laso-Marsetti.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 2 of 4 of this article. Click here to view the first page.

Installing Carthage

Now that you’ve gained some background knowledge, it’s time to learn how ruthlessly simple Carthage is!

At Carthage’s core is a command-line tool that assists with fetching and building dependencies.

There are two ways to install this tool:

  • Download and run a .pkg installer for the latest release.
  • Use the Homebrew package manager.

Just as Carthage helps install packages for Cocoa development, Homebrew helps install useful Unix tools for macOS.

For the purposes of this Carthage tutorial, you’ll use the .pkg installer.

Download the latest release of Carthage from GitHub. Then, under Assets, select Carthage.pkg.

Double-click Carthage.pkg to run the installer. Click Continue, select a location to install to, click Continue again and finally click Install.

Note: When you attempt to run the installer, you may see a message stating: “Carthage.pkg can’t be opened because it is from an unidentified developer.” If so, Control-click the installer and choose Open from the context menu.

And you’re done! To check that Carthage installed correctly, open Terminal and run the following command:

carthage version

This shows you the Carthage version you installed.

Next, you need to tell Carthage which libraries to install using a Cartfile.

Creating Your First Cartfile

A Cartfile is a simple text file that describes your project’s dependencies to Carthage, so it can determine what to install. Each line in a Cartfile states where to fetch a dependency, the dependency’s name, and optionally, which version to use. A Cartfile is the equivalent of a CocoaPods Podfile.

To create your first one, go to Terminal, then navigate to the root directory of your project – the directory that contains your .xcodeproj file – using the cd command:

cd ~/Path/To/Starter/Project

Create an empty Cartfile with the touch command:

touch Cartfile

Then open the file in Xcode for editing:

open -a Xcode Cartfile

If you’re familiar with another text editor, like Vim, feel free to use that instead. Don’t, however, use TextEdit to edit the file. With TextEdit, it’s too easy to accidentally use “smart quotes” instead of straight quotes, which confuse Carthage.

Add the following lines to the Cartfile and save it:

github "Alamofire/Alamofire" == 4.9.0
github "Alamofire/AlamofireImage" ~> 3.4

These two lines tell Carthage that your project requires Alamofire version 4.9.0 and the latest version of AlamofireImage that’s compatible with version 3.4.

The Cartfile Format

You write Cartfiles in a subset of OGDL: Ordered Graph Data Language. This sounds fancy, but it’s quite simple. There are two key pieces of information on each line of a Cartfile:

  • Dependency origin: This tells Carthage where to fetch a dependency. Carthage supports two types of origins:
    • github for GitHub-hosted projects (the clue’s in the name!). You specify a GitHub project in the Username/ProjectName format, as you did with the Cartfile above.
    • git for generic Git repositories hosted elsewhere. You use the git keyword followed by the path to the git repository, whether that’s a remote URL using git://, http://, or ssh:// or a local path to a Git repository on your development machine.
  • Dependency version: Here, you tell Carthage which version of a dependency you want to use. There are several options at your disposal, depending on how specific you want to be:
    • == 1.0: Indicates “Use exactly version 1.0.”
    • >= 1.0: Means “Use version 1.0 or higher.”
    • ~> 1.0: Translates to “Use any version that’s compatible with 1.0,” meaning any version up to the next major release.
    • Branch name / tag name / commit name means “Use this specific git branch / tag / commit”. For example, you could specify master, or a commit hash like 5c8a74a.

Here are some examples:

If you specify ~> 1.7.5, Carthage considers any version from 1.7.5 up to, but not including 2.0, compatible.

Likewise, if you specify ~> 2.0, Carthage uses version 2.0 or any later versions, but not 3.0 or above.

Carthage uses semantic versioning to determine compatibility.

If you don’t specify a version, Carthage will use the latest version that’s compatible with your other dependencies. You can see examples of each of these options in Carthage’s README file.

Building Dependencies

Now that you have a Cartfile, it’s time to put it to use and install some dependencies!

Be sure to replace path to Xcode 11 with your machine’s specific path to Xcode 11.

Note: This Carthage tutorial uses Swift 5. At the time of writing, Swift 5 is only available in Xcode 11. Ensure you’ve configured your command line tools to use Xcode 11 by running the following command from Terminal:
sudo xcode-select -s <path to Xcode 11>/Xcode.app/Contents/Developer 

Be sure to replace path to Xcode 11 with your machine’s specific path to Xcode 11.

sudo xcode-select -s <path to Xcode 11>/Xcode.app/Contents/Developer 

Close your Cartfile in Xcode and head back to Terminal. Run the following command:

carthage update --platform iOS

This instructs Carthage to clone the Git repositories from the Cartfile, then to build each dependency into a framework. You’ll see output that shows the results, like this:

*** Cloning AlamofireImage
*** Cloning Alamofire
*** Checking out Alamofire at "4.9.0"
*** Checking out AlamofireImage at "3.6.0"
*** xcodebuild output can be found in /var/folders/bj/3hftn5nn0qlfrs2tqrydgjc80000gn/T/carthage-xcodebuild.7MbtQO.log
*** Building scheme "Alamofire iOS" in Alamofire.xcworkspace
*** Building scheme "AlamofireImage iOS" in AlamofireImage.xcworkspace

--platform iOS ensures that Carthage only builds frameworks for iOS. If you don’t specify a platform, Carthage will build frameworks for all platforms — often both Mac and iOS — supported by the library.

If you’d like to take a look at further options, run carthage help update.

By default, Carthage performs its checkouts and builds in a new directory named Carthage, which you’ll find in the same location as your Cartfile. Open this directory now by running:

open Carthage

You’ll see a Finder window appear that contains two directories: Build and Checkouts. Take a moment to see what Carthage created for you.

Generated Carthage/ folder contents

Building Artifacts

When you use CocoaPods, it makes several changes to your Xcode project and binds the result, along with a special Pods project, into an Xcode workspace.

Carthage is a little different. It checks the code for your dependencies and builds the result into binary frameworks. It’s then up to you to integrate the frameworks into your project.

This sounds like extra work, but it’s beneficial. It only takes a few steps, and you’re more aware of the changes to your project as a result.

When you run carthage update, Carthage creates a couple of files and directories for you:

Carthage update folder structure and hierarchy

  • Cartfile.resolved: This file serves as a companion to the Cartfile. It defines exactly which versions of your dependencies Carthage selected for installation. It’s strongly recommended to commit this file to your version control repository. Its presence ensures that other developers can get started quickly by using the exact same dependency versions.
  • Carthage directory, containing two subdirectories:
    • Build: This contains the built framework for each dependency. You can integrate these into your project, and you’ll do so shortly. Carthage either builds each framework from source or downloads it from the project’s Releases page on GitHub.
    • Checkouts: This is where Carthage checks out the source code for each dependency that’s ready to build into frameworks. Carthage maintains its own internal cache of dependency repositories, so it doesn’t have to clone the same source multiple times for different projects.