How to Create a CocoaPod in Swift

In this tutorial, you’ll learn how to create a CocoaPod containing your Swift code, assets, and storyboard files. You’ll also learn all about Podspec files. By Keegan Rush.

4.5 (23) · 2 Reviews

Download materials
Save for later
Share
Update note: Keegan Rush updated this tutorial for Xcode 10.0, Swift 4.2, and CocoaPods 1.5.3. Joshua Greene wrote the original.

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!

Getting Started

Note: This instructions and sample code in this tutorial require you to make Xcode 10 your default Xcode. To determine which Xcode is your default, enter 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 Flavor model.
  • ScoopCell: Is a custom collection view cell that contains a ScoopView, which is also backed by an instance of the Flavor model class.

Storyboard Annotated

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!

Swift Ninja

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:

New Cocoa Touch Framework

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.

Note: The directory where you save your development pods is important because you’ll need to reference this directory from your Podfile during local development.

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:

  1. It uses the local files on your machine for the pod, instead of fetching them from a remote repository.
  2. 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 pod install again.

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:

cd ~/Documents/Libraries/RWPickFlavor
pod init
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
end

This declares that RWPickFlavor will have external dependencies on both Alamofire and MBProgressHUD.

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.

By omitting 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.

Note: You’ll need at least CocoaPods version 1.5.0 for this to work. If your version is less than 1.5.0, enter the following in Terminal to install the latest version of CocoaPods:
sudo gem install CocoaPods