iOS library support both Cocoapods and Swift Package Manager

Konstantinos Nikoloutsos
Dev Genius
Published in
4 min readJan 8, 2022

--

Cocoapods and SwiftPM are some of the most popular package managers.
By supporting both in your open-source library, you potentially increase the developers who will use it.

🚨Remember the most important thing all package managers want to know is where are the source files in order to distribute them. Each package manager has its own way of configuring that.

So let’s jump straight to some practical examples in order to understand how to support both. For this, we will use as an example a recent open-source library I built called FancyGradient.

Swift Package Manager 🔥

The configuration happens on a file named Package.swift (aka manifest).
This is the file we need to edit to let SPM know what files to include.

Note: Every SPM library must contain a manifest file called Package.swift

EPackage.swift in folder

By default SPM anticipate the developer to put:

  • His source code into → Sources >> {{target Name}}folder 📁
  • His tests (XCTests) → Sources >> {{testTarget Name} folder 📁
Red-underline shows the target and testTarget names.

Note: If I change the folder nameSources >> FancyGradient into something else the library will not be able to compile. Of course because SPM doesn’t know how to find the files 🚨

But what if you wanted a different structure or different folder names? Don’t worry developer’s of SPM got your back 💪

For changing the default behavior of SPM you need to tamper with the Package.swift manifest.

We changed default directory into Foo

path the parameter in target gives you the ability to change the path that SPM will try to look for finding your files. (in that case the source code). 👀

So now we know how SPM locates our files for sharing the library with other developers. ✅

Note: After pushing this to github remember to add a tag-version of your library and push it. So that when someone uses your library, he will know the version he has or decide what version to get.

Versions of FancyGradient

Cocoapods 🔥

Cocoapods has a configuration file called {{LibraryName}}.podspec

FancyGradient.podspec

The red-underlined line lets Cocoapods know where to search for the source code. We can of course change the name of the folder structure as we did in SPM manifest.

Note: Sources/FancyGradient/**/*.{h,m,swift} will include all .h .m .swift files in the shipped library.

Cocoapods + SPM 🚀

So now that we already know how each package manager configuration works, we can support both. ✅

If you already support Cocoapods but not SPM you can follow the following steps. 👇

  1. Create a new empty SPM package
  2. (optional) Rename the folder structure (just we saw above)
  3. Copy source code files from your current library into sources >> {{Library Name }}. Do the same for tests (If you just creating your library don’t copy something 😄)
  4. With the current structure add cocoa pods (If you already have don’t worry)
  5. Alter cocoa pods source_files in .podspec files (to let it know the path to search for the source code)
  6. Add and push a new tag version of your library to Github.
  7. Publish Cocoapods(you’ll use the command line for that) and push everything to GitHub

Now your library supports both cocoa pods and SPM.

Note: In case you forget or have any doubht on how to do this just open another github library that supports both package managers and see how it is doing that. You don’t have to reinvent the wheel 👀

Extra lovely tip for those who come down here ❤️

For those coming to the end here is a useful tip learned from pointfreeco.
Suppose you want to add a demo project inside your library, you will get this.

Demo folder doesn’t look nice in

You can get rid of the Demo folder inside the package by manually creating an empty file Package.swift inside the Demo ⭐️

Add empty Package.swift in demo
A demo is ignored by SPM.

So again if you don't want the docs folder just add an empty manifest inside it and kaboom 🎉.

Extra resources:

If you liked you learned don’t forget to leave a 👏

--

--