Making a CocoaPod

Creating your own CocoaPod is fairly straight forward. If you already have a separate component, you're most of the way there. This guide is an overview to the entire process, with the other guides in this section serving as more of a deep-dive for more advanced users.

<The Pod Files

There are only a few differences between a CocoaPod and a generic open source library. The most important ones, aside from the actual source, are the .podspec and LICENSE. We do not accept libraries into the trunk without a code license. For information on what license to choose, we suggest reading this article on CodingHorror or tl;dr Legal.

We recommend letting CocoaPods do the hard work here. Running pod lib create [pod name] will set you up with a well thought out library structure allowing you to easily include your files and get started quickly, we have a guide for this.

<Development

You can work on the library from its folder on your system.

Alternatively you can work from an application project using the :path option:

pod 'Name', :path => '~/code/Pods/'

<Testing

You can test the syntax of your Podfile by linting the pod against the files of its directory, this won't test the downloading aspect of linting.

$ cd ~/code/Pods/NAME
$ pod lib lint

Before releasing your new Pod to the world its best to test that you can install your pod successfully into an Xcode project. You can do this in a couple of ways:

Push your podspec to your repository, then create a new Xcode project with a Podfile and add your pod to the file like so:

pod 'NAME', :git => 'https://example.com/URL/to/repo/NAME.git'

Then run

pod install
-- or --
pod update

Alternatively if you have a separate Xcode project for your unit tests you can use a Podfile for this project that references your development podspec

xcodeproj 'NAMETests'
workspace '../NAME'

pod 'NAME', :path => '../'

<Release

Once you have a release ready you'll need to make the corresponding tag. First run a quick pod lib lint then create your tag and push it.

The release workflow is similar to the following.

$ cd ~/code/Pods/NAME
$ edit NAME.podspec
# set the new version to 0.0.1
# set the new tag to 0.0.1
$ pod lib lint

$ git add -A && git commit -m "Release 0.0.1."
$ git tag '0.0.1'
$ git push --tags

Submitting Open Source Code

Once your tags are pushed you can use the command pod trunk push NAME.podspec to send your library to the Specs repo. For more information on getting this setup see Getting Setup With Trunk.

Submitting Private Code

Once your tags are pushed you can use the command pod repo push [repo] NAME.podspec to send your library to the named private specs repo. For more information on getting this setup see Private CocoaPods.

<Library Versioning

There is, unfortunately, often an issue of developers not interpreting version numbers well or assigning emotional value to certain version numbers.

However, arbitrary revisions as version is not a good idea for a library manager instead of a proper version number (see Semantic Versioning). Let us explain how, in an ideal world, we’d prefer people to interact with it:

  • “I want to start using CocoaLumberjack, the current version will be fine for now.” So the dev adds a dependency on the lib without a version requirement and pod installs which will use the latest version:

    pod 'CocoaLumberjack'

  • Some time into the future, the dev wants to update the dependencies, and to do so runs the install command again, which will now install the version of the lib which is the latest version at that time.

  • At some point the dev is finished on the client work (or a newer version of the lib changes the API and the changes aren’t needed) so the dev adds a version requirement to the dependency. For instance, consider that the author of the lib follows the semver guidelines, you can somewhat trust that between ‘1.0.7’ and ‘1.1.0’ no API changes will be made, but only bug fixes. So instead of requiring a specific version, the dev can specify that any ‘1.0.x’ is allowed as long as it’s higher than ‘1.0.7’:

pod 'CocoaLumberjack', '~> 1.0.7'

The point is that developers can easily keep track of newer versions of dependencies, by simply running pod install again, which they might otherwise do less if they had to change everything manually. CocoaPods uses a less stringent form of Semantic versioning in that it will not force you to use X.Y.Z, you can use X.Y versions.

<CocoaPods Versioning Specifics

CocoaPods uses RubyGems versions for specifying pod spec versions. The RubyGems Versioning Policies describes the rules used for interpreting version numbers. The RubyGems version specifiers describes exactly how to use the comparison operators that specify dependency versions.

Following the pattern established in RubyGems, pre-release versions can also be specified in CocoaPods. A pre-release of version 1.2, for example, can be specified by 1.2-beta3. In this example, the dependency specifier ~> 1.2-beta will match 1.2-beta3.

<Documenting a Pod

Right now the best place to get information on documenting your Pods in anticipation of CocoaDocs and Xcode 5 support is via NSHipster's blog post on Documentation. CocoaDocs will release an appledoc parsed code based on your Podspec's public API roughly 15 minutes after it is pushed. More information on CocoaDocs can be found on the CocoaDocs developer readme

<Where can I ask questions?

We have multiple avenues for support, here they are in the order we prefer.

  • Stack Overflow, get yourself some internet points. This keeps the pressure off the CocoaPods dev team and gives us time to work on the project and not support. One of the advantages of using Stack Overflow is that the answer is then easily accessible for others.

  • CocoaPods Mailing List, the mailing list is mainly used for announcements of related projects and for support.

<< External resources