Creating CocoaPods

Share this article

In a previous article we introduced CocoaPods, a dependency management tool for cocoa development, and covered the why and how of using it. In this article, we are going to look at how to create your own CocoaPod and make it available for others to use in their projects.

For this tutorial, I have a class that formats phone numbers that I would like to make into a CocoaPod. My phone formatting library consists of the class files JKEPhoneNumberFormatter.h and JKEPhoneNumberFormatter.m and a README.md file.

To begin, run the following command to make sure that you have the latest CocoaPods version. The command will install CocoaPods if it isn’t already installed and will update if it is installed and needs updating.

[sudo] gem install cocoapods

Use of the sudo command depends on your Ruby installation. More on this in the previous tutorial.

I recommended that you use the latest version of CocoaPods because the command syntax may have changed and new features added.

To check the CocoaPods version, run pod --version. At the time of writing this article, the latest version is 0.33.1.

There are various files that you need to include in your CocoaPod. These include the class files, Podspec, license, assets used in your library and a demo project that shows the use of your Pod (this is run when a user types pod try [LIB_NAME] to see what it does before using it in a project).

You can create your own Pod directory structure and files or you can use a command that CocoaPods makes available which creates a template library structure to get you started quickly. This generates a Podspec file (we will look at what this is later in the article), license file, readme and a demo project complete with test files and a Podfile.

To use the generator, run the command below.

pod lib create [pod name]

You will be presented with four questions that will determine how your library is set up. You will be asked if you want a demo project created for you, what testing framework you want to use, if you want view based testing and what you want to use as your class prefix.

The following is an example of a directory structure created after running the command. After the files are generated, the project is opened in Xcode.

Example
    JKEPhoneNumberFormatter
    JKEPhoneNumberFormatter.xcodeproj
    JKEPhoneNumberFormatter.xcworkspace
    Podfile
    Podfile.lock
    Pods
    Tests
JKEPhoneNumberFormatter.podspec
LICENSE
Pod
    Assets
    Classes
README.md

We will look at how to manually create a Pod. An advantage of this method is that you get a lean library structure containing only what you need. With the generator, you might have to go over the generated files deleting what you don’t need. The generator has its advantages of course, for example the quick setup of a library structure and letting you know what is generally expected as part of a Pod library. Which method to use is a matter of preference.

To start off, I have placed my class files in a Classes folder. This is not a requirement, but it is better to separate out the different parts of the Pod in folders for ease of use and readability. The folder name is also up to you. Another common naming convention is to give the folder the name of the library, for example in my case, the folder would be labelled JKEPhoneNumberFormatter.

I have included a demo project which is simply a project that shows your library in use. The project is of a simple single view iPhone app that imports the JKEPhoneNumberFormatter class and uses its method to output a formatted phone number.

I have also included README and LICENSE files. The README gives a brief summary of what the class does and how to use it. You need to include a code license in you library otherwise it will not be accepted to the CocoaPods Trunk, which is used to publish Pods (more on CocoaPods Trunk later). If you aren’t sure what license to use you can read about different software licenses at tl;dr Legal. It is a helpful website that summarizes different software license terms in an easy to understand way, without legal jargon.

Below is my directory structure.

Classes
    JKEPhoneNumberFormatter.h
    JKEPhoneNumberFormatter.m
Demo
    AddressBook.xcodeproj
    AddressBook
    AddressBookTests
README.md
LICENSE

Next, we create a Podspec file in the root of our library structure. This is a file that describes a version of a Pod library. It contains details of the Pod including its version number, source location, dependencies, etc.

Navigate to the root of your library structure and run the following command. You can manually create your own file, but the command below generates a template that you can start with.

pod spec create JKEPhoneNumberFormatter

The Podspec file is written in Ruby and it contains the Pod’s specification. The generated template has a list of attributes with comments explaining what they are for. The final spec file will depend on your library and the information you chose to make available. The CocoaPods guides give examples of different spec files for different types of libraries.

Below is my final spec file.

I have removed all comments and some attributes.

Pod::Spec.new do |s|

    s.name         = "JKEPhoneNumberFormatter"
    s.version      = "0.1.0"
    s.summary      = "NSFormatter subclass for formatting phone numbers."
    s.homepage     = "https://github.com/echessa/JKEPhoneNumberFormatter"
    s.license      = { :type => "MIT", :file => "LICENSE" }
    s.author       = "Joyce Echessa"
    s.source       = { :git => "https://github.com/echessa/JKEPhoneNumberFormatter.git", :tag => "0.1.0" }
    s.source_files  = "Classes", "Classes/*.{h,m}"
    s.requires_arc = false

end

I have only included a few attributes, namely, the name, version, summary, homepage, license, author, source, requires_arc and source_files. I pushed the library to Github and added a tag of 0.1.0 to mark the version number. Apart from git, the following source attributes are also supported: hg, bzr, svn and HTTP. The spec templates lists available attributes, you can edit it as per your needs. The syntax used is pretty straightforward, but if you have any problems, you can read more on the Spec syntax used.

Once you are done editing, run the pod spec lint command to check if your spec file is valid. If there is a missing attribute that is required, a syntax error, a problem accessing the source repository or any other problem, you will get an error message.

pod spec lint JKEPhoneNumberFormatter.podspec

After the spec passes validation, your library is now ready to be published to the CocoaPods spec repository.

Before CocoaPods version 0.33, submitting a Pod involved making pull requests on Github. This proved inefficient and it was difficult for the CocoaPods maintainers to manage the repositories. At times Podspecs would be submitted without passing pod lint and would have to be rejected during review by the team. This manual reviewing wasn’t scalable as CocoaPods became more popular. It was also difficult to keep track of unauthorised commits from people other than the original library author(s).

The CocoaPods Trunk was launched to solve these problems. It is a web service that allows developers to publish Pods directly from the command-line, without the need to create a pull-request.

With the Trunk, the first person to publish a pod becomes the owner of the pod name in the spec repo. The owner can then add other owners. Only the owners will be able to publish subsequent versions of the pod. Owners are also responsible for ensuring that their podspec works properly. The Trunk service only validates that the spec has the required bare-minimum meta-data needed to register the podspec.

To use the CocoaPods Trunk, you have to first register your machine with the Trunk service. To register, run the pod trunk register command. This registers a new account, or creates a new session if you have previously registered. If you are registering to Trunk for the first time, you have to give both your email and name. If you have registered before, you can omit your name.

There are other options you can add to the command. Below I use the description option to identify the machine I am using for that session. This makes it easier to identify your sessions later especially if you use different computers.

pod trunk register joyce@mydomain.com 'Joyce Echessa' --description='Home Desktop'

An email will be sent to the email address you registered with a confirmation link.

To publish your Pod, run the following command with the name of your podspec file.

pod trunk push JKEPhoneNumberFormatter.podspec

It will first validate your podspec before pushing the CocoaPod.

That’s it. You have just created a CocoaPod and made it available on the Pod repository for others to use. You should note that this will be a public pod. CocoaPods also allows you to create Private Pods. The steps for creating the Pod are the same but instead of using Trunk to push to the public spec repo, you push to your own repository. I won’t get into the whole process here, but if you want more information on this, the CocoaPods guides have a great outline of how to do this. An advantage of private pods is that you can have some internal libraries that are easily accessible to team members in your organization via CocoaPods.

Conclusion

We have looked at how you can turn your library into a CocoaPod and make it available for others. If you want to find out more about CocoaPods, a good place to start is reading through the CocoaPods guides.

Joyce EchessaJoyce Echessa
View Author

I am a web developer who dabbles in mobile development from time to time. You can find me on Twitter @joyceechessa to see what I’m up to.

chriswcocoapoddependency managementtools
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week