Creating a Private CocoaPod

by

On a recent project I was tasked with creating a private CocoaPod to be used by several internal iOS applications. As I did my research to do this, I found that the information was spread across several sites and not 100% clear (the CocoaPods site’s documentation could use some love in places). I am taking this opportunity to assist those that follow to create, organize, test and distribute a private Pod. I’ll also throw in a few tips for general pod development.

This guide assumes you have a basic understanding of CocoaPods and iOS development.

Step 1. Create the Git Repos

You’ll need two git repos for your private Pod; One for the Pod itself, and another to serve as your ‘Podspec’ repo. The Podspec repo is where information about your private Pod(s) is maintained. To add the private Podspec to your local CocoaPods installation, run the following command:

pod repo add [REPO_NAME] [SOURCE_URL]

where the [REPO_NAME] is a name you’ll use to reference the Podspec repo and [SOURCE_URL] is the git url for the repo. If everything worked correctly, you should see a directory for your repo on your machine in the ~/.cocoapods/repos directory.

Step 2. Generate your Pod with pod lib create

CocoaPods has a nice utility to help you setup your Pod project along with a test app and testing framework. Simply run the command:

pod lib create [POD_NAME]

with [POD_NAME] being the name of the Pod you are creating. You will be prompted by an interactive script to select various options for your new Pod project. The end result will be a XCode workspace that is setup for you to commence Pod development. If you already have some source files to add to the project, you can copy them into the Pod/Classes folder that has conveniently been created for you. You’ll also have a default test app created where you can write unit tests and view tests for your Pod.

Step 3. Edit the .podspec file

A Podspec, or Spec, describes a version of a Pod library. It includes details about where the source files are located, which files to use, the build settings to apply, dependencies, frameworks used and other general metadata such as the name, version, and description for the Pod. Below is an example of a Podspec for one of Grio’s private Pods:

Pod::Spec.new do |s|
  s.name             = "GrioCommon"
  s.version          = "1.1.7"
  s.summary          = "Common functions for Grio iOS apps"
  s.description      = <<-DESC
Common functions for Grio iOS apps. functionality includes:
* Universal User Settings
* Localytics libraries and support files
DESC
 s.homepage         = "https://github.com/Grio/GrioCommoniOS"
  s.license          = 'MIT'
  s.author           = { "Doug Kadlecek" =&gt; "dkadlecek@grio.com" }
  s.source           = { :git => "https://github.com/Grio/GrioCommoniOS.git", :tag => s.version.to_s }

  s.platform     = :ios, '7.0'
  s.requires_arc = true

  s.source_files = 'Pod/Classes/*.{h,m}'

  s.resource_bundles = {
    'GrioCommon' => ['Pod/Assets/*.*']
  }

  s.frameworks = 'UIKit'
  s.dependency 'AFNetworking', '~> 2.4.1'

  s.subspec 'Analytics' do |as|
    as.source_files = 'Pod/Classes/Analytics/*.{h,m}', 'Pod/Classes/*.{h,m}'
    as.dependency 'Localytics-iOS-Client', '~> 2.71.0'
  end

  s.subspec 'UserSettings' do |us|
    us.source_files = 'Pod/Classes/UserSettings/*.{h,m}'
  end
end

A couple things to note here: We are using subspecs to group functionality within the Pod. This is most easily accomplished by creating sub-directories under the main Pod directory (created for you in the pod lib create command) and placing the corresponding source files in those directories. Subspecs are a great way to organize your Pod’s functionality and code. Note that since CocoaPods automatically creates the XCode project for your Pod, you must use directories, not XCode Groups to organize the source files.

Notice the command/setting:

  s.resource_bundles = {
    'GrioCommon' => ['Pod/Assets/*.*']
  }

This creates a resource bundle for us named GrioCommon with the contents populated from the Pod/Assets directory. These assets can now be accessed from our Pod code thusly:

NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle]
  pathForResource:@"GrioCommon" ofType:@"bundle"]];
NSString *filePath = [bundle pathForResource:@"grio-user-settings" ofType:@"js"];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];

You can leverage assets in resource bundles to access any non-code support files you need (a javascript file in this case).

There are lots of other options to explore in your Podspec. You can find more information about Podspec on the CocoaPods official site at http://guides.cocoapods.org/syntax/podspec.html

Step 4. Push your repo

Now that you’ve built and tested your Pod, it’s time to deploy it to your private Podspec repo! The first thing you need to do is tag your Pod’s git repo:

git tag '1.1.7'
git push --tags

The tag should match the version setting in your .podspec file. Once you tag is pushed up to your Pod repo, you can use the command

pod repo push [REPO_NAME] [POD_NAME].podspec

to send your library to the named private Podspec repo. If you want other members of your development team to be able to access and use Pods from your private Podspec repo, they must add the private repo to their local Cocoapods installation with the command:

pod repo add [REPO_NAME] [SOURCE_URL]

Congratulations! You have now published your first private Pod. You can now more easily leverage the benefits of reusable code in your internal iOS projects.

1 Comment

  1. This is not very clear…

    A couple things to note here: We are using subspecs to group functionality within the Pod. This is most easily accomplished by creating sub-directories under the main Pod directory (created for you in the pod lib create command) and placing the corresponding source files in those directories. Subspecs are a great way to organize your Pod’s functionality and code. Note that since CocoaPods automatically creates the XCode project for your Pod, you must use directories, not XCode Groups to organize the source files.

Leave a Reply

Your email address will not be published. Required fields are marked *