I have never been a fan of CocoaPods due to its intrusiveness in the build process and insistence on creating Xcode project workspaces. Unfortunately managing dependencies through the use of Git submodules is no better. How many times have you told yourself, “Okay, I understand submodules now” only to be met with fatal: reference is not a tree:
when trying to do a git submodule update
? Perhaps I’m dense, but I shouldn’t have to turn to Google every time I check out a project which uses submodules.
In the tutorial HTTP JSON Request with Swift and Alamofire we used the git submodule approach to add the Alamofire framework as a dependency to our Xcode project. Let’s now look at a new approach to managing framework dependencies with Carthage.
Carthage was developed to make framework dependency management in your Xcode projects just a bit easier. Luckily for us, Alamofire now supports using Carthage, and we can leverage that support in our project to get rid of the git submodule approach.
To get started with Carthage, you’ll first need to install Homebrew. If you have never used Homebrew before, you’re in for a real treat. To install Homebrew open a terminal and paste:
1 |
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" |
Follow the prompts and once Homebrew is properly installed then you can install carthage with brew install carthage
.
==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/carthage-0.5.2.yosemite.bottle.tar.gz
Already downloaded: /Library/Caches/Homebrew/carthage-0.5.2.yosemite.bottle.tar.gz
==> Pouring carthage-0.5.2.yosemite.bottle.tar.gz
[emoji beer mug] /usr/local/Cellar/carthage/0.5.2: 157 files, 34M
Now, let’s look at how to add Alamofire to our project using Carthage. The first step is to create a Cartfile
in our project folder. The Cartfile
is what you might expect: a list of dependencies (and where to fetch them from) for our project. Our Cartfile
will contain a single dependency on Alamofire.
1 |
github "Alamofire/Alamofire" >= 1.1 |
Run carthage update
. Carthage will now check out and build Alamofire.
% carthage update
*** Fetching Alamofire
*** Checking out Alamofire at "2f39b8634ab85cd6b3a55bbcfdec8cbb6463a6ee"
*** xcodebuild output can be found in /var/folders/yn/ljzrn5hd4g3fxsj4klwkhbkm0000gp/T/carthage-xcodebuild.wAPiQR.log
*** Building scheme "Alamofire iOS" in Alamofire.xcworkspace
*** Building scheme "Alamofire OSX" in Alamofire.xcworkspace
Once completed you should see a new file and new folder in your project directory: Cartfile.resolved
and Carthage
, respectively.
You are going to want to check in both Cartfile
and Cartfile.resolved
, so add them to your repository.
git add Cartfile
git add Cartfile.resolved
You do not need to add the Carthage
folder, so you can add it to your .gitignore
file if you like.
Now, let’s add the build output from Carthage to our project. First, go to your project’s General tab and locate the section Linked Frameworks and Libraries. You can either drag-and-drop the built framework from the Finder, or use the + button and navigate to the folder in Xcode.
You should see the framework added to the list:
Now, go to Build Phases and create a new Run Script phase. The script contents will be:
1 |
/usr/local/bin/carthage copy-frameworks |
Then add an Input File as the framework you want to copy, i.e., Alamofire.framework
.
That’s it! With your Xcode project set up to pull in the built framework that Carthage created, you’re ready to build and run! Much easier than using than CocoaPods or git submodules.
Gotchas
If you are iOS developer that likes to stay on the bleeding edge you undoubtedly have both the release and beta versions of Xcode installed on your Mac. If you build your projects solely within Xcode there’s typically no conflict between the two, but since Carthage builds your frameworks from the command-line, the version of Xcode selected by xcodebuild
matters. For example, if your xcodebuild
is set to use the release version of Xcode and you run carthage update
and then include that framework in an Xcode beta project, you will likely get the error Module file was created by an older version
. To resolve this use xcode-select
to switch xcodebuild
to use the beta version of Xcode:
1 |
sudo xcode-select -s /Applications/Xcode-Beta.app |
As of February 28, 2015, the Alamofire main branch hasn’t been updated to support Xcode 6.3 (and by extension, Swift 1.2). To continue working with Alamofire in your Xcode 6.3 projects, update your Cartfile
to specify a branch dependency:
1 |
github "Alamofire/Alamofire" "xcode-6.3" |
Run carthage update
and Carthage will checkout the xcode-6.3
branch of Alamofire and compile it. If you get a build failure make sure you’re using the right xcodebuild
!
% xcodebuild -version
Xcode 6.3
Build version 6D520o
Get the Code
You can check out our example application (for details on the application, see our post here)of using Alamofire and Carthage on Bitbucket. There are two branches, carthage
and carthage-xcode-6.3
.
If you’re using Xcode 6.1 then you will want to use the carthage
branch:
1 2 3 4 5 |
git clone git@bitbucket.org:joeiachievedit/alamofire-translator translator cd translator git checkout carthage sudo xcode-select -s /Applications/Xcode.app carthage update |
If you’re using Xcode 6.3 (which is beta at the time of this writing):
1 2 3 4 5 |
git clone git@bitbucket.org:joeiachievedit/alamofire-translator translator cd translator git checkout carthage-xcode-6.3 sudo xcode-select -s /Applications/Xcode-Beta.app carthage update |
Note! If you open the translator project and try to build and are met with No such module 'Alamofire'
you didn’t build Alamofire with carthage update
first!