Making My CocoaPods Compatible with SPM
[10/19, 2024] |
Hi, this is Tomo. Since CocoaPods seems to be in maintenance mode, and it's unclear if it will support Xcode 16, I decided to make my custom CocoaPods compatible with Swift Package Manager (SPM).
Looking back, I could have structured things even more towards SPM. But hopefully, this post will help others trying to do the same.
In this post, I’ll show how to make your project compatible with both SPM and CocoaPods.
Process
- Adjust the folder structure for SPM.
- Update the podspec file.
- Regenerate .xcworkspace.
- Verify CocoaPods functionality.
- Add Package.swift.
- Verify SPM functionality.
- Test in an app.
Adjust the Folder Structure for SPM
Let's say you have a Pod named "Pod_Name". Change the structure as follows:
Before:
Pod_Name/
Pod_Name/
Classes/
Assets/
Example/
Pod_Name.podspec
etc..
After (for SPM):
Pod_Name/
Sources/
Classes/
Assets/
Tests/
Example/
Pod_Name.podspec
etc...
Update the podspec File
Update the paths to match the new structure.
Before:
s.source_files = 'Pod_Name/Classes/**/*'
s.resource_bundles = {
'RFTextKit' => ['Pod_Name/Assets/*.png']
}
After (for SPM):
s.source_files = 'Sources/Classes/**/*'
s.resource_bundles = {
'RFTextKit' => ['Sources/Assets/*.png']
}
Verify CocoaPods Functionality
Regenerate the .xcworkspace by running pod init or pod update in the Example folder. Make sure the project works properly.
Create the Package.swift File
Add Package.swift to the root of the project (Pod_Name).
Updated structure:
Pod_Name/
Sources/
Classes/
Assets/
Tests/
Example/
Pod_Name.podspec
Package.swift <--Added
etc...
Package.swift contents:
// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "Pod_Name",
platforms: [
.iOS(.v12),
],
products: [
.library(
name: "Pod_Name",
targets: ["Pod_Name"]
),
],
dependencies: [
//Add dependency for AnotherPod if needed
.package(url: "git@github.com:xxx/anotherpod.git", from: "1.0.0")
],
targets: [
.target(
name: "MLanguage",
dependencies: [
// Add dependency for AnotherPod if needed
.product(name: "AnotherPod", package: "anotherpod"),
],
path: "Sources/Classes",
resources: [
.process("../Assets")
]
),
.testTarget(
name: "Pod_Name",
dependencies: ["Pod_Name"]
)
]
)
If no dependencies are required, remove the relevant parts.
I'm still new to this, so I'm not fully confident yet. Since the path is set to "Sources/Classes," I've used a relative path from there to specify the location of the assets.
If I fully adapt the structure to SPM, I could make things simpler by placing the asset files directly under Sources, alongside the class files, without using nested directories. This would make the setup more straightforward.
Verify SPM Functionality
When Xcode finds Package.swift at the project’s root, it will recognize the folder as an SPM package. Right-click Package.swift, open it with Xcode, and check if the project builds properly.
Commit the SPM-Compatible Version
If everything works, update the version in your podspec, tag it, and push it to your repository.
Configuring IDEPackageSupportUseBuiltinSCM
For private SPM repositories, access can be done by:
- Logging into GitHub through Xcode.
- Using a token (I haven't looked into this much 😅).
- Using SSH settings from your Mac.
CocoaPods works with SSH settings, and we want Xcode to do the same. I found this helpful article suggesting that setting IDEPackageSupportUseBuiltinSCM to YES allows Xcode to use SSH configurations.
defaults write com.apple.dt.Xcode IDEPackageSupportUseBuiltinSCM YES
The last parameter:
- YES: Xcode uses SSH settings.
- NO: Xcode requires login settings.
Once this is set to YES, navigate to:
Files > Add Package Dependencies... > Then Open The Window
In Xcode 16, enter your SSH URL (e.g., git@github.com:xxxx/pod_name.git) in the popup. If the package loads successfully, you’re good to go! Then, add the package to your app, build it, and you're done.
The best part? You can still maintain CocoaPods support while migrating to SPM!
Since I have dozens of custom pods, I’ll be gradually migrating them over 😭.