How to Ship a CocoaPod
After a long, frustrating day of failing to find a good iOS library for
parsing Well-Known-Text (WKT), we gave up and decided to write something. If
WKT strings are what you are getting, you can parse geometries from the
coordinate data there to draw polygons on a
MKMapView. In fact, WKT can
define 18 different geometric objects, but we were only dealing with polygons
and multi-polygons, and only exterior ones at that.
MooreChris and I spiked on it late one day. Over
the next two nights I put together a
WKTParser class that takes a
string of WKT, and spits out arrays of
MKPolygons, making use a lot of
Peter’s existing coordinate generating
It seemed obvious that we should share this, since we went through so much pain to find something and came up empty-handed. We love CocoaPods so it seemed like a great opportunity to contribute something.
I began looking at a few existing repos to get a feel for how to organize the
code into a CocoaPod library. Judging by the variety of what I saw, the first
lesson was, perhaps there’s no right way to do it. What matters is that your
.podspec can find the core files and classes it needs to install.
CocoaPods docs suggest creating publicly accessible directory named “Classes”
for this, but it seemed that most libraries put their core files in a top-
level folder having the same name as the repo. Although technically this
collection of core files is all that is needed to install a CocoaPod, the core
files most often exists inside of a larger repository. That repository usually
includes a sample application that demonstrates the functionality of the
library, or serves as a basis for running the library’s tests against.
WKTParser was no exception. Even though I was only shipping one class,
WKTParser needed an
AppDelegate to run my Kiwi specs against. I landed on
this structure for the library.
I created an empty iOS application named
WKTParserExample, in xCode.
WKTParserExample is the also the group / directory where the
would be generated and the sample project would be created. I Installed Kiwi,
using CocoaPods. And I worked my specs into
WKTParserTest/ and my core
WKTParser/. Getting the directory structure on the filesystem
in line with the project references in xCode is still a bit confusing to me. I
landed on a pattern of creating and organizing the files on the filesystem,
and then dragging them into the xCode project navigator from Finder. After
setting up and configuring my test target, specs were passing,
I pushed it up to github, and I was ready to take the next step.
How do you make a public repo a CocoaPod? It’s pretty painless, you publish a
.podspec file. It only needs to be publicly accessible, the top level of
your library’s github repo is a fine place to put this. Consumers of your
library can simply point to this public
.podspec in their Podfile to install
your code. If you’re generally unfamiliar with
CocoaPods, see MooreChris’ earlier article, CocoaPods
and You: A Primer for the Uninformed.
After installing CocoaPods on your machine, you can run
pod spec create
ProjectName to generate a
ProjectName.podspec file. In the
set configurations that tell CocoaPods where to fetch the project, where the
important source files are, what the license is, and dependencies that should
be installed. The commented contents of the generated file will lead you
through this. The only other trick is that you’ll need to version your repo
git tag and set that version number in the
.podspec config as well.
You’ll make a couple gaffs. Run
pod spec lint ProjectName.podspec and
correct any reported issues.
That’s it! Find a project you want to integrate your classes into, and put a
line for your library in the Podfile, pointing to your publicly accessible
pod 'WKTParser', :podspec => "https://raw.github.com/joelturnbull/WKTParser/0.0.1/WKTParser.podspec"
pod install and watch CocoaPods install your library!
Enjoy, and in the meantime, submit your podspec to the canonical github repo. You’ll need to make sure it lints
without issue. When it’s accepted, consumers of your CocoaPod will no longer
need to specify the
:podspec location, only the name.