Comparing iOS Dependency Managers
If Nothing Else, This Post Wins for Most Repositories Created
At the request of Matt I'm diving into the differences between Carthage and Cocoapods.
To be able to talk about these remotely well, I took the time to build a sample framework, make it Carthage and Cocoapods friendly, then build a project that imports and pulls data from the framework. They're so small and useless this also pushed me to make a private Cocoapods spec repo just so that I didn't push a literally useless framework to the real index.
For an extra challenge, the framework is in Swift whereas the projects are in Objective-C.
If you're interested in the code involved, there's the framework, the Carthage example, the Cocoapods example, and the private podspec repo.
Intent of Design
The biggest difference between Cocoapods and Carthage is intent of the tool. Cocoapods is focused on making it as easy as possible to integrate community code into your own project. This means a central index, automating almost every bit of code configuration on the user side, and generally trying to hide the rough edges.
Carthage on the other hand is designed to be the simplest dependency manager possible. It downloads and builds a series of frameworks. Finding them is up to you, integrating them is up to you, etc.
Before iOS 8, having to configure your project by hand was sort of miserable. With the steps now being: "add frameworks to project, add step to copy preprocess files for release builds." The only configuration gotcha that I ran integrating Carthage was that I needed to set the "Embedded Content Contains Swift Code" build option to "YES."
As a Maintainer
Implementing Carthage support required:
- Create framework
- Make the build target for the framework public
- Tag release with semantic version number
Implementing Cocoapods support required:
- Create framework
- Write podspec, including listing headers and source files, among other things
- Lint podspec
- Submit podspec to either private or public podspec repo.
Carthage support for the project was almost an afterthought. Cocoapods support requires writing the podspec, which is really a Ruby build script. It wasn't a huge effort, but it's a separate step that has nothing to do with the rest of the code in the project.
Some of the rough edges and bad documentation that I ran into can be written off to the fact that framework support just was released, but more of it has to do with the fact that Cocoapods was built around the assumptions of pre iOS8 app development, which are still often valid assumptions as many developers still support iOS7.