You’re probably familiar with some well-known, open-source CocoaPods dependencies like Alamofire or MBProgressHUD. But sometimes you can’t find a pod with the exact functionality you need, or you may want to separate a large project into smaller, reusable components.
Fortunately, it’s easy to create your own CocoaPod! Through this tutorial, you’ll learn the following:
- How to create a CocoaPod to host shared, reusable code.
- How to use CocoaPods with either frameworks or static libraries.
- How to publish your new CocoaPod to your own spec repository.
If you’ve already created a Cocoa Touch framework for your component, you’ve done most of the hard work. If you haven’t, don’t panic, as it’s really straightforward.
If you’ve only ever created classes as part of an iOS app, that’s OK, too. You can easily create a new pod by pulling out classes and functionality that make sense for your particular use case.
This tutorial picks up where How to Use CocoaPods With Swift ends. If you’ve never used CocoaPods before, then that tutorial is definitely a prerequisite to this one.
Otherwise, grab yourself a hot cup of “cocoa” (sorry, couldn’t resist!) and read on!
xcode-select -p in a Terminal window. If your version is Xcode 9 or earlier, use the command
sudo xcode-select -s path-to-Xcode-10 to change it.
Your top client is Ice Cream Shop, Inc. Its ice cream is so popular it can’t keep up with customer orders at the counter. It has recruited you to create a sleek iOS app that will allow customers to order ice cream right from their phones. You’ve started developing the app, and it’s coming along well.
Download the starter project using the Download Materials button at the top or bottom of this tutorial. This is an updated version of the final project from How to Use CocoaPods With Swift.
The app has a few pod dependencies already included in the download, so you don’t need to run
pod install to install them.
Note: If you worked through How to Use CocoaPods With Swift, this next section may seem familiar; it’s simply a review of that tutorial. Feel free to skip ahead as needed.
Open IceCreamShop.xcworkspace and then Main.storyboard, found in the Views group, to see how the app is laid out.
Here’s a quick overview of the Choose Your Flavor scene, which is the heart of the app:
- PickFlavorViewController: Handles user interaction, such as when the user selects an ice cream flavor.
- PickFlavorDataSource: Is the data source for the collection view that displays ice cream flavors.
IceCreamView: Is a custom view that displays an ice cream cone and is backed by a
ScoopCell: Is a custom collection view cell that contains a ScoopView, which is also backed by an instance of the
The top managers at Ice Cream Shop, Inc. really like how the app is coming along, but they’ve added a new requirement: Ice cream retailers need to have the same choose-your-own-flavor functionality in their apps.
Wait, that wasn’t in the original design. But that should be no problem for a Swift ninja like you!
Can you guess how you’re going to do this? Yep, you’re going to pull this functionality into its own CocoaPod!
Setting Up Your Pod
Create a new Xcode project and select iOS ▸ Framework & Library ▸ Cocoa Touch Framework, and then click Next:
Enter RWPickFlavor for the product name and Swift for the language. Click Next.
For the purposes of this tutorial, you’ll create the project in ~/Documents/Libraries. Choose the Documents folder in your home directory. If you don’t already have a Libraries folder, click on the New Folder button in the bottom and create it.
Finally, choose the Libraries folder and click Create.
Normally, when you use CocoaPods, you include dependencies in your Podfile like this:
pod 'PodName', '~> 1.0'
But when you’re developing your own CocoaPod, you’ll instead specify a local path, like this:
pod 'MyPodName', :path => '~/Path/To/Folder/Containing/My/Pod'
There are two benefits to this approach:
- It uses the local files on your machine for the pod, instead of fetching them from a remote repository.
- When you’re using a pod, you normally shouldn’t make changes to any of the pod’s classes because these will be overwritten the next time you run
pod install. By using the
:path =>syntax, your local path is treated as the source for the CocoaPod, and any changes you make will change the files in this location. So your changes will still exist even when you run
While you can use a different location for your development pods, in general, put them in ~/Documents/Libraries. This is also a good location if you work with a team of developers since CocoaPods knows to expand the tilde as the user’s home directory.
You can also use other CocoaPods as dependencies of your pod. To do so, you need to create a Podfile for your CocoaPod to specify them during development.
Close Xcode, and enter the following commands in Terminal to create the Podfile:
open -a Xcode Podfile
This creates a new Podfile and opens it in Xcode.
Replace the entire contents of the new Podfile with the following:
platform :ios, '12.0'
target 'RWPickFlavor' do
pod 'Alamofire', '~> 4.7'
pod 'MBProgressHUD', '~> 1.1.0', :modular_headers => true
Using Swift Static Libraries
Prior to CocoaPods 1.5.0, CocoaPods did not work with static libraries. If you depended on a pod that contains Swift, you had to integrate CocoaPods into your project via frameworks instead of static libraries by specifying
use_frameworks! in your Podfile.
This is no longer the case. As of CocoaPods 1.5.0, you can use CocoaPods with static libraries! This is a big deal, since not all libraries you might depend on are shipped as frameworks. Dynamic frameworks also come with a launch-time performance impact that some apps need to avoid.
use_frameworks! from your Podfile, CocoaPods will integrate into your app using static libraries instead. Your Objective-C dependencies still need to work as a module, however. MBProgressHUD is an Objective-C dependency that does not support modules. Luckily, by adding
:modular_headers => true to the MBProgressHUD dependency in the Podfile, CocoaPods adds module support for us.
sudo gem install CocoaPods